diff options
Diffstat (limited to 'bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/cleanup/ElementNodeCleanupHandler.java')
-rw-r--r-- | bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/cleanup/ElementNodeCleanupHandler.java | 745 |
1 files changed, 0 insertions, 745 deletions
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/cleanup/ElementNodeCleanupHandler.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/cleanup/ElementNodeCleanupHandler.java deleted file mode 100644 index 937cd234d5..0000000000 --- a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/internal/cleanup/ElementNodeCleanupHandler.java +++ /dev/null @@ -1,745 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2009 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.wst.html.core.internal.cleanup; - - - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.text.edits.InsertEdit; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.wst.css.core.internal.formatter.CSSSourceFormatter; -import org.eclipse.wst.css.core.internal.formatter.CSSSourceFormatterFactory; -import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleDeclarationAdapter; -import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel; -import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode; -import org.eclipse.wst.html.core.internal.Logger; -import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames; -import org.eclipse.wst.sse.core.internal.cleanup.IStructuredCleanupHandler; -import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter; -import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList; -import org.eclipse.wst.sse.core.utils.StringUtils; -import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration; -import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; -import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap; -import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; -import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; -import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator; -import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -// nakamori_TODO: check and remove CSS formatting - -public class ElementNodeCleanupHandler extends AbstractNodeCleanupHandler { - - /** Non-NLS strings */ - protected static final String START_TAG_OPEN = "<"; //$NON-NLS-1$ - protected static final String END_TAG_OPEN = "</"; //$NON-NLS-1$ - protected static final String TAG_CLOSE = ">"; //$NON-NLS-1$ - protected static final String EMPTY_TAG_CLOSE = "/>"; //$NON-NLS-1$ - protected static final String SINGLE_QUOTES = "''"; //$NON-NLS-1$ - protected static final String DOUBLE_QUOTES = "\"\""; //$NON-NLS-1$ - protected static final char SINGLE_QUOTE = '\''; //$NON-NLS-1$ - protected static final char DOUBLE_QUOTE = '\"'; //$NON-NLS-1$ - - public Node cleanup(Node node) { - IDOMNode renamedNode = (IDOMNode) cleanupChildren(node); - - // call quoteAttrValue() first so it will close any unclosed attr - // quoteAttrValue() will return the new start tag if there is a - // structure change - renamedNode = quoteAttrValue(renamedNode); - - // insert tag close if missing - // if node is not comment tag - // and not implicit tag - if (!((IDOMElement) renamedNode).isCommentTag() && (renamedNode.getStartStructuredDocumentRegion() != null)) { - IDOMModel structuredModel = renamedNode.getModel(); - - // save start offset before insertTagClose() - // or else renamedNode.getStartOffset() will be zero if - // renamedNode replaced by insertTagClose() - int startTagStartOffset = renamedNode.getStartOffset(); - - // for start tag - IStructuredDocumentRegion startTagStructuredDocumentRegion = renamedNode.getStartStructuredDocumentRegion(); - insertTagClose(structuredModel, startTagStructuredDocumentRegion); - - // update renamedNode and startTagStructuredDocumentRegion after - // insertTagClose() - renamedNode = (IDOMNode) structuredModel.getIndexedRegion(startTagStartOffset); - startTagStructuredDocumentRegion = renamedNode.getStartStructuredDocumentRegion(); - - // for end tag - IStructuredDocumentRegion endTagStructuredDocumentRegion = renamedNode.getEndStructuredDocumentRegion(); - if (endTagStructuredDocumentRegion != startTagStructuredDocumentRegion) - insertTagClose(structuredModel, endTagStructuredDocumentRegion); - } - - // call insertMissingTags() next, it will generate implicit tags if - // there are any - // insertMissingTags() will return the new missing start tag if one is - // missing - // then compress any empty element tags - // applyTagNameCase() will return the renamed node. - // The renamed/new node will be saved and returned to caller when all - // cleanup is done. - renamedNode = insertMissingTags(renamedNode); - renamedNode = compressEmptyElementTag(renamedNode); - renamedNode = insertRequiredAttrs(renamedNode); - renamedNode = applyTagNameCase(renamedNode); - applyAttrNameCase(renamedNode); - cleanupCSSAttrValue(renamedNode); - - return renamedNode; - } - - /** - * Checks if cleanup should modify case. Returns true case should be - * preserved, false otherwise. - * - * @param element - * @return true if element is case sensitive, false otherwise - */ - private boolean shouldPreserveCase(IDOMElement element) { - // case option can be applied to no namespace tags - return !element.isGlobalTag(); - /* - * ModelQueryAdapter mqadapter = (ModelQueryAdapter) - * element.getAdapterFor(ModelQueryAdapter.class); ModelQuery mq = - * null; CMNode nodedecl = null; if (mqadapter != null) mq = - * mqadapter.getModelQuery(); if (mq != null) nodedecl = - * mq.getCMNode(node); // if a Node isn't recognized as HTML or is and - * cares about case, do not alter it // if (nodedecl == null || - * (nodedecl instanceof HTMLCMNode && ((HTMLCMNode) - * nodedecl).shouldIgnoreCase())) if (! - * nodedecl.supports(HTMLCMProperties.SHOULD_IGNORE_CASE)) return - * false; return - * ((Boolean)cmnode.getProperty(HTMLCMProperties.SHOULD_IGNORE_CASE)).booleanValue(); - */ - } - - /** - * Checks if cleanup should force modifying element name to all lowercase. - * - * @param element - * @return true if cleanup should lowercase element name, false otherwise - */ - private boolean isXMLTag(IDOMElement element) { - return element.isXMLTag(); - } - - protected void applyAttrNameCase(IDOMNode node) { - IDOMElement element = (IDOMElement) node; - if (element.isCommentTag()) - return; // do nothing - - int attrNameCase = HTMLCorePreferenceNames.ASIS; - if (!shouldPreserveCase(element)) { - if (isXMLTag(element)) - attrNameCase = HTMLCorePreferenceNames.LOWER; - else - attrNameCase = getCleanupPreferences().getAttrNameCase(); - } - - NamedNodeMap attributes = node.getAttributes(); - int attributesLength = attributes.getLength(); - - for (int i = 0; i < attributesLength; i++) { - IDOMNode eachAttr = (IDOMNode) attributes.item(i); - String oldAttrName = eachAttr.getNodeName(); - String newAttrName = oldAttrName; - /* - * 254961 - all HTML tag names and attribute names should be in - * English even for HTML files in other languages like Japanese or - * Turkish. English locale should be used to convert between - * uppercase and lowercase (otherwise "link" would be converted to - * Turkish "I Overdot Capital"). - */ - if (attrNameCase == HTMLCorePreferenceNames.LOWER) - newAttrName = oldAttrName.toLowerCase(Locale.US); - else if (attrNameCase == HTMLCorePreferenceNames.UPPER) - newAttrName = oldAttrName.toUpperCase(Locale.US); - - if (newAttrName.compareTo(oldAttrName) != 0) { - int attrNameStartOffset = eachAttr.getStartOffset(); - int attrNameLength = oldAttrName.length(); - - IDOMModel structuredModel = node.getModel(); - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - replaceSource(structuredModel, structuredDocument, attrNameStartOffset, attrNameLength, newAttrName); - } - } - } - - protected IDOMNode applyTagNameCase(IDOMNode node) { - IDOMElement element = (IDOMElement) node; - if (element.isCommentTag()) - return node; // do nothing - - int tagNameCase = HTMLCorePreferenceNames.ASIS; - - if (!shouldPreserveCase(element)) { - if (isXMLTag(element)) - tagNameCase = HTMLCorePreferenceNames.LOWER; - else - tagNameCase = getCleanupPreferences().getTagNameCase(); - } - - String oldTagName = node.getNodeName(); - String newTagName = oldTagName; - IDOMNode newNode = node; - - /* - * 254961 - all HTML tag names and attribute names should be in - * English even for HTML files in other languages like Japanese or - * Turkish. English locale should be used to convert between uppercase - * and lowercase (otherwise "link" would be converted to Turkish "I - * Overdot Capital"). - */ - if (tagNameCase == HTMLCorePreferenceNames.LOWER) - newTagName = oldTagName.toLowerCase(Locale.US); - else if (tagNameCase == HTMLCorePreferenceNames.UPPER) - newTagName = oldTagName.toUpperCase(Locale.US); - - IDOMModel structuredModel = node.getModel(); - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - - IStructuredDocumentRegion startTagStructuredDocumentRegion = node.getStartStructuredDocumentRegion(); - if (startTagStructuredDocumentRegion != null) { - ITextRegionList regions = startTagStructuredDocumentRegion.getRegions(); - if (regions != null && regions.size() > 0) { - ITextRegion startTagNameRegion = regions.get(1); - int startTagNameStartOffset = startTagStructuredDocumentRegion.getStartOffset(startTagNameRegion); - int startTagNameLength = startTagStructuredDocumentRegion.getTextEndOffset(startTagNameRegion) - startTagNameStartOffset; - - replaceSource(structuredModel, structuredDocument, startTagNameStartOffset, startTagNameLength, newTagName); - newNode = (IDOMNode) structuredModel.getIndexedRegion(startTagNameStartOffset); // save - // new - // node - } - } - - IStructuredDocumentRegion endTagStructuredDocumentRegion = node.getEndStructuredDocumentRegion(); - if (endTagStructuredDocumentRegion != null) { - ITextRegionList regions = endTagStructuredDocumentRegion.getRegions(); - if (regions != null && regions.size() > 0) { - ITextRegion endTagNameRegion = regions.get(1); - int endTagNameStartOffset = endTagStructuredDocumentRegion.getStartOffset(endTagNameRegion); - int endTagNameLength = endTagStructuredDocumentRegion.getTextEndOffset(endTagNameRegion) - endTagNameStartOffset; - - if (startTagStructuredDocumentRegion != endTagStructuredDocumentRegion) - replaceSource(structuredModel, structuredDocument, endTagNameStartOffset, endTagNameLength, newTagName); - } - } - - return newNode; - } - - protected Node cleanupChildren(Node node) { - Node parentNode = node; - - if (node != null) { - Node childNode = node.getFirstChild(); - HTMLCleanupHandlerFactory factory = HTMLCleanupHandlerFactory.getInstance(); - while (childNode != null) { - // cleanup this child node - IStructuredCleanupHandler cleanupHandler = factory.createHandler(childNode, getCleanupPreferences()); - childNode = cleanupHandler.cleanup(childNode); - - // get new parent node - parentNode = childNode.getParentNode(); - - // get next child node - childNode = childNode.getNextSibling(); - } - } - - return parentNode; - } - - /** - */ - protected void cleanupCSSAttrValue(IDOMNode node) { - if (node == null || node.getNodeType() != Node.ELEMENT_NODE) - return; - IDOMElement element = (IDOMElement) node; - if (!element.isGlobalTag()) - return; - - Attr attr = element.getAttributeNode("style"); //$NON-NLS-1$ - if (attr == null) - return; - String value = getCSSValue(attr); - if (value == null) - return; - String oldValue = ((IDOMNode) attr).getValueSource(); - if (oldValue != null && value.equals(oldValue)) - return; - attr.setValue(value); - } - - /** - */ - private ICSSModel getCSSModel(Attr attr) { - if (attr == null) - return null; - INodeNotifier notifier = (INodeNotifier) attr.getOwnerElement(); - if (notifier == null) - return null; - INodeAdapter adapter = notifier.getAdapterFor(IStyleDeclarationAdapter.class); - if (adapter == null) - return null; - if (!(adapter instanceof IStyleDeclarationAdapter)) - return null; - IStyleDeclarationAdapter styleAdapter = (IStyleDeclarationAdapter) adapter; - return styleAdapter.getModel(); - } - - /** - */ - private String getCSSValue(Attr attr) { - ICSSModel model = getCSSModel(attr); - if (model == null) - return null; - ICSSNode document = model.getDocument(); - if (document == null) - return null; - INodeNotifier notifier = (INodeNotifier) document; - CSSSourceFormatter formatter = (CSSSourceFormatter) notifier.getAdapterFor(CSSSourceFormatter.class); - // try another way to get formatter - if (formatter == null) - formatter = CSSSourceFormatterFactory.getInstance().getSourceFormatter(notifier); - if (formatter == null) - return null; - StringBuffer buffer = formatter.cleanup(document); - if (buffer == null) - return null; - return buffer.toString(); - } - - private boolean isEmptyElement(IDOMElement element) { - Document document = element.getOwnerDocument(); - if (document == null) - // undefined tag, return default - return false; - - ModelQuery modelQuery = ModelQueryUtil.getModelQuery(document); - if (modelQuery == null) - // undefined tag, return default - return false; - - CMElementDeclaration decl = modelQuery.getCMElementDeclaration(element); - if (decl == null) - // undefined tag, return default - return false; - - return (decl.getContentType() == CMElementDeclaration.EMPTY); - } - - protected IDOMNode insertEndTag(IDOMNode node) { - IDOMElement element = (IDOMElement) node; - - int startTagStartOffset = node.getStartOffset(); - IDOMModel structuredModel = node.getModel(); - IDOMNode newNode = null; - - if (element.isCommentTag()) { - // do nothing - } - else if (isEmptyElement(element)) { - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - IStructuredDocumentRegion startStructuredDocumentRegion = node.getStartStructuredDocumentRegion(); - ITextRegionList regions = startStructuredDocumentRegion.getRegions(); - ITextRegion lastRegion = regions.get(regions.size() - 1); - replaceSource(structuredModel, structuredDocument, startStructuredDocumentRegion.getStartOffset(lastRegion), lastRegion.getLength(), EMPTY_TAG_CLOSE); - - if (regions.size() > 1) { - ITextRegion regionBeforeTagClose = regions.get(regions.size() - 1 - 1); - - // insert a space separator before tag close if the previous - // region does not have extra spaces - if (regionBeforeTagClose.getTextLength() == regionBeforeTagClose.getLength()) - replaceSource(structuredModel, structuredDocument, startStructuredDocumentRegion.getStartOffset(lastRegion), 0, " "); //$NON-NLS-1$ - } - } - else { - String tagName = node.getNodeName(); - String endTag = END_TAG_OPEN.concat(tagName).concat(TAG_CLOSE); - - IDOMNode lastChild = (IDOMNode) node.getLastChild(); - int endTagStartOffset = 0; - if (lastChild != null) - // if this node has children, insert the end tag after the - // last child - endTagStartOffset = lastChild.getEndOffset(); - else - // if this node does not has children, insert the end tag - // after the start tag - endTagStartOffset = node.getEndOffset(); - - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - replaceSource(structuredModel, structuredDocument, endTagStartOffset, 0, endTag); - } - - newNode = (IDOMNode) structuredModel.getIndexedRegion(startTagStartOffset); // save - // new - // node - - return newNode; - } - - protected IDOMNode insertMissingTags(IDOMNode node) { - boolean insertMissingTags = getCleanupPreferences().getInsertMissingTags(); - IDOMNode newNode = node; - - if (insertMissingTags) { - IStructuredDocumentRegion startTagStructuredDocumentRegion = node.getStartStructuredDocumentRegion(); - if (startTagStructuredDocumentRegion == null) { - // implicit start tag; generate tag for it - newNode = insertStartTag(node); - startTagStructuredDocumentRegion = newNode.getStartStructuredDocumentRegion(); - } - - IStructuredDocumentRegion endTagStructuredDocumentRegion = newNode.getEndStructuredDocumentRegion(); - - ITextRegionList regionList = startTagStructuredDocumentRegion.getRegions(); - if (startTagStructuredDocumentRegion != null && regionList != null && regionList.get(regionList.size() - 1).getType() == DOMRegionContext.XML_EMPTY_TAG_CLOSE) { - - } - else { - if (startTagStructuredDocumentRegion == null) { - // start tag missing - if (isStartTagRequired(newNode)) - newNode = insertStartTag(newNode); - } - else if (endTagStructuredDocumentRegion == null) { - // end tag missing - if (isEndTagRequired(newNode)) - newNode = insertEndTag(newNode); - } - } - } - - return newNode; - } - - protected IDOMNode insertStartTag(IDOMNode node) { - IDOMElement element = (IDOMElement) node; - if (element.isCommentTag()) - return node; // do nothing - - IDOMNode newNode = null; - - String tagName = node.getNodeName(); - String startTag = START_TAG_OPEN.concat(tagName).concat(TAG_CLOSE); - int startTagStartOffset = node.getStartOffset(); - - IDOMModel structuredModel = node.getModel(); - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - replaceSource(structuredModel, structuredDocument, startTagStartOffset, 0, startTag); - newNode = (IDOMNode) structuredModel.getIndexedRegion(startTagStartOffset); // save - // new - // node - - return newNode; - } - - protected void insertTagClose(IDOMModel structuredModel, IStructuredDocumentRegion flatNode) { - if ((flatNode != null) && (flatNode.getRegions() != null)) { - ITextRegionList regionList = flatNode.getRegions(); - ITextRegion lastRegion = regionList.get(regionList.size() - 1); - if (lastRegion != null) { - String regionType = lastRegion.getType(); - if ((regionType != DOMRegionContext.XML_EMPTY_TAG_CLOSE) && (regionType != DOMRegionContext.XML_TAG_CLOSE)) { - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - - // insert ">" after lastRegion of flatNode - // as in "<a</a>" if flatNode is for start tag, or in - // "<a></a" if flatNode is for end tag - replaceSource(structuredModel, structuredDocument, flatNode.getTextEndOffset(lastRegion), 0, ">"); //$NON-NLS-1$ - } - } - } - } - - protected boolean isEndTagRequired(IDOMNode node) { - if (node == null) - return false; - return node.isContainer(); - } - - /** - * The end tags of HTML EMPTY content type, such as IMG, and HTML - * undefined tags are parsed separately from the start tags. So inserting - * the missing start tag is useless and even harmful. - */ - protected boolean isStartTagRequired(IDOMNode node) { - if (node == null) - return false; - return node.isContainer(); - } - - protected boolean isXMLType(IDOMModel structuredModel) { - boolean result = false; - - if (structuredModel != null && structuredModel != null) { - IDOMDocument document = structuredModel.getDocument(); - - if (document != null) - result = document.isXMLType(); - } - - return result; - } - - protected IDOMNode quoteAttrValue(IDOMNode node) { - IDOMElement element = (IDOMElement) node; - if (element.isCommentTag()) - return node; // do nothing - - boolean quoteAttrValues = getCleanupPreferences().getQuoteAttrValues(); - IDOMNode newNode = node; - - if (quoteAttrValues) { - NamedNodeMap attributes = newNode.getAttributes(); - int attributesLength = attributes.getLength(); - ISourceGenerator generator = node.getModel().getGenerator(); - - for (int i = 0; i < attributesLength; i++) { - attributes = newNode.getAttributes(); - attributesLength = attributes.getLength(); - IDOMAttr eachAttr = (IDOMAttr) attributes.item(i); - // ITextRegion oldAttrValueRegion = eachAttr.getValueRegion(); - String oldAttrValue = eachAttr.getValueRegionText(); - if (oldAttrValue == null) { - IDOMModel structuredModel = node.getModel(); - if (isXMLType(structuredModel)) { - // TODO: Kit, please check. Is there any way to not - // rely on getting regions from attributes? - String newAttrValue = "=\"" + eachAttr.getNameRegionText() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ - - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - replaceSource(structuredModel, structuredDocument, eachAttr.getNameRegionEndOffset(), 0, newAttrValue); - newNode = (IDOMNode) structuredModel.getIndexedRegion(node.getStartOffset()); // save - // new - // node - } - } - else { - - char quote = StringUtils.isQuoted(oldAttrValue) ? oldAttrValue.charAt(0) : DOUBLE_QUOTE; - String newAttrValue = generator.generateAttrValue(eachAttr, quote); - - // There is a problem in - // StructuredDocumentRegionUtil.getAttrValue(ITextRegion) - // when the region is instanceof ContextRegion. - // Workaround for now... - if (oldAttrValue.length() == 1) { - char firstChar = oldAttrValue.charAt(0); - if (firstChar == SINGLE_QUOTE) - newAttrValue = SINGLE_QUOTES; - else if (firstChar == DOUBLE_QUOTE) - newAttrValue = DOUBLE_QUOTES; - } - - if (newAttrValue != null) { - if (newAttrValue.compareTo(oldAttrValue) != 0) { - int attrValueStartOffset = eachAttr.getValueRegionStartOffset(); - int attrValueLength = oldAttrValue.length(); - int startTagStartOffset = node.getStartOffset(); - - IDOMModel structuredModel = node.getModel(); - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - replaceSource(structuredModel, structuredDocument, attrValueStartOffset, attrValueLength, newAttrValue); - newNode = (IDOMNode) structuredModel.getIndexedRegion(startTagStartOffset); // save - // new - // node - } - } - } - } - } - - return newNode; - } - - private IDOMNode insertRequiredAttrs(IDOMNode node) { - boolean insertRequiredAttrs = getCleanupPreferences().getInsertRequiredAttrs(); - IDOMNode newNode = node; - - if (insertRequiredAttrs) { - List requiredAttrs = getRequiredAttrs(newNode); - if (requiredAttrs.size() > 0) { - NamedNodeMap currentAttrs = node.getAttributes(); - List insertAttrs = new ArrayList(); - if (currentAttrs.getLength() == 0) - insertAttrs.addAll(requiredAttrs); - else { - for (int i = 0; i < requiredAttrs.size(); i++) { - String requiredAttrName = ((CMAttributeDeclaration) requiredAttrs.get(i)).getAttrName(); - boolean found = false; - for (int j = 0; j < currentAttrs.getLength(); j++) { - String currentAttrName = currentAttrs.item(j).getNodeName(); - if (requiredAttrName.compareToIgnoreCase(currentAttrName) == 0) { - found = true; - break; - } - } - if (!found) - insertAttrs.add(requiredAttrs.get(i)); - } - } - if (insertAttrs.size() > 0) { - IStructuredDocumentRegion startStructuredDocumentRegion = newNode.getStartStructuredDocumentRegion(); - int index = startStructuredDocumentRegion.getEndOffset(); - ITextRegion lastRegion = startStructuredDocumentRegion.getLastRegion(); - if (lastRegion.getType() == DOMRegionContext.XML_TAG_CLOSE) { - index--; - lastRegion = startStructuredDocumentRegion.getRegionAtCharacterOffset(index - 1); - } - else if (lastRegion.getType() == DOMRegionContext.XML_EMPTY_TAG_CLOSE) { - index = index - 2; - lastRegion = startStructuredDocumentRegion.getRegionAtCharacterOffset(index - 1); - } - MultiTextEdit multiTextEdit = new MultiTextEdit(); - try { - for (int i = insertAttrs.size() - 1; i >= 0; i--) { - CMAttributeDeclaration attrDecl = (CMAttributeDeclaration) insertAttrs.get(i); - String requiredAttributeName = attrDecl.getAttrName(); - String defaultValue = attrDecl.getDefaultValue(); - if (defaultValue == null) - defaultValue = ""; //$NON-NLS-1$ - String nameAndDefaultValue = " "; //$NON-NLS-1$ - if (i == 0 && lastRegion.getLength() > lastRegion.getTextLength()) - nameAndDefaultValue = ""; //$NON-NLS-1$ - nameAndDefaultValue += requiredAttributeName + "=\"" + defaultValue + "\""; //$NON-NLS-1$ //$NON-NLS-2$ - multiTextEdit.addChild(new InsertEdit(index, nameAndDefaultValue)); - // BUG3381: MultiTextEdit applies all child - // TextEdit's basing on offsets - // in the document before the first TextEdit, not - // after each - // child TextEdit. Therefore, do not need to - // advance the index. - // index += nameAndDefaultValue.length(); - } - multiTextEdit.apply(newNode.getStructuredDocument()); - } - catch (BadLocationException e) { - // log or now, unless we find reason not to - Logger.log(Logger.INFO, e.getMessage()); - } - } - } - } - - return newNode; - } - - - protected ModelQuery getModelQuery(Node node) { - ModelQuery result = null; - if (node.getNodeType() == Node.DOCUMENT_NODE) { - result = ModelQueryUtil.getModelQuery((Document) node); - } - else { - result = ModelQueryUtil.getModelQuery(node.getOwnerDocument()); - } - return result; - } - - protected List getRequiredAttrs(Node node) { - List result = new ArrayList(); - - ModelQuery modelQuery = getModelQuery(node); - if (modelQuery != null) { - CMElementDeclaration elementDecl = modelQuery.getCMElementDeclaration((Element) node); - if (elementDecl != null) { - CMNamedNodeMap attrMap = elementDecl.getAttributes(); - Iterator it = attrMap.iterator(); - CMAttributeDeclaration attr = null; - while (it.hasNext()) { - attr = (CMAttributeDeclaration) it.next(); - if (attr.getUsage() == CMAttributeDeclaration.REQUIRED) { - result.add(attr); - } - } - } - } - - return result; - } - - /** - * <p>Compress empty element tags if the prefence is set to do so</p> - * - * @copyof org.eclipse.wst.xml.core.internal.cleanup.ElementNodeCleanupHandler#compressEmptyElementTag - * - * @param node the {@link IDOMNode} to possible compress - * @return the compressed node if the given node should be compressed, else the node as it was given - */ - private IDOMNode compressEmptyElementTag(IDOMNode node) { - boolean compressEmptyElementTags = getCleanupPreferences().getCompressEmptyElementTags(); - IDOMNode newNode = node; - - IStructuredDocumentRegion startTagStructuredDocumentRegion = newNode.getFirstStructuredDocumentRegion(); - IStructuredDocumentRegion endTagStructuredDocumentRegion = newNode.getLastStructuredDocumentRegion(); - - //only compress tags if they are empty - if ((compressEmptyElementTags && startTagStructuredDocumentRegion != endTagStructuredDocumentRegion && - startTagStructuredDocumentRegion != null)) { - - //only compress end tags if its XHTML or not a container - if(isXMLTag((IDOMElement)newNode) || !newNode.isContainer()) { - ITextRegionList regions = startTagStructuredDocumentRegion.getRegions(); - ITextRegion lastRegion = regions.get(regions.size() - 1); - // format children and end tag if not empty element tag - if (lastRegion.getType() != DOMRegionContext.XML_EMPTY_TAG_CLOSE) { - NodeList childNodes = newNode.getChildNodes(); - if (childNodes == null || childNodes.getLength() == 0 || (childNodes.getLength() == 1 && (childNodes.item(0)).getNodeType() == Node.TEXT_NODE && ((childNodes.item(0)).getNodeValue().trim().length() == 0))) { - IDOMModel structuredModel = newNode.getModel(); - IStructuredDocument structuredDocument = structuredModel.getStructuredDocument(); - - int startTagStartOffset = newNode.getStartOffset(); - int offset = endTagStructuredDocumentRegion.getStart(); - int length = endTagStructuredDocumentRegion.getLength(); - structuredDocument.replaceText(structuredDocument, offset, length, ""); //$NON-NLS-1$ - newNode = (IDOMNode) structuredModel.getIndexedRegion(startTagStartOffset); // save - - offset = startTagStructuredDocumentRegion.getStart() + lastRegion.getStart(); - structuredDocument.replaceText(structuredDocument, offset, 0, "/"); //$NON-NLS-1$ - newNode = (IDOMNode) structuredModel.getIndexedRegion(startTagStartOffset); // save - } - } - } - } - - return newNode; - } -}
\ No newline at end of file |