/******************************************************************************* * Copyright (c) 2005, 2014 Spring IDE Developers * 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: * Spring IDE Developers - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.beans.ui.editor.util; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.StringTokenizer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.JarEntryFile; import org.eclipse.jdt.internal.ui.javaeditor.JarEntryEditorInput; import org.eclipse.jdt.internal.ui.text.java.ProposalInfo; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Region; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.internal.Workbench; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; 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.ui.internal.contentassist.ContentAssistUtils; import org.eclipse.wst.xml.core.internal.document.ElementImpl; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest; import org.springframework.beans.PropertyAccessor; import org.springframework.beans.PropertyAccessorUtils; import org.springframework.ide.eclipse.beans.core.BeansCorePlugin; import org.springframework.ide.eclipse.beans.core.BeansCoreUtils; import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils; import org.springframework.ide.eclipse.beans.core.model.IBean; import org.springframework.ide.eclipse.beans.core.model.IBeansComponent; import org.springframework.ide.eclipse.beans.core.model.IBeansConfig; import org.springframework.ide.eclipse.beans.core.model.IBeansConfigSet; import org.springframework.ide.eclipse.beans.core.model.IBeansProject; import org.springframework.ide.eclipse.beans.core.model.IImportedBeansConfig; import org.springframework.ide.eclipse.beans.ui.editor.Activator; import org.springframework.ide.eclipse.beans.ui.editor.IPreferencesConstants; import org.springframework.ide.eclipse.beans.ui.editor.namespaces.IClassNameProvider; import org.springframework.ide.eclipse.beans.ui.editor.namespaces.IReferenceableElementsLocator; import org.springframework.ide.eclipse.beans.ui.editor.namespaces.NamespaceUtils; import org.springframework.ide.eclipse.core.io.ZipEntryStorage; import org.springframework.ide.eclipse.core.java.Introspector; import org.springframework.ide.eclipse.core.java.JdtUtils; import org.springframework.ide.eclipse.ui.editors.ZipEntryEditorInput; import org.springsource.ide.eclipse.commons.ui.SpringUIUtils; 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; /** * Collection of helper methods for beans XML editor. * @author Christian Dupuis * @author Torsten Juergeleit * @author Terry Denney * @author Leo Dos Santos */ @SuppressWarnings("restriction") public class BeansEditorUtils { protected static final String AMPERSTAND = "&"; //$NON-NLS-1$ protected static final String AMPERSTAND_ENTITY = "&&;"; //$NON-NLS-1$ protected static final String CARRIAGE_RETURN = "\r"; //$NON-NLS-1$ protected static final String CARRIAGE_RETURN_ENTITY = "\\r"; //$NON-NLS-1$ protected static final String CR = "\r"; //$NON-NLS-1$ protected static final String CRLF = "\r\n"; //$NON-NLS-1$ protected static final String DELIMITERS = " \t\n\r\f"; //$NON-NLS-1$ protected static final String DOUBLE_QUOTE = "\""; //$NON-NLS-1$ protected static final char DOUBLE_QUOTE_CHAR = '\"'; protected static final String DOUBLE_QUOTE_ENTITY = """; //$NON-NLS-1$ protected static final String EQUAL_SIGN = "="; //$NON-NLS-1$ protected static final String EQUAL_SIGN_ENTITY = "="; //$NON-NLS-1$ protected static final String GREATER_THAN = ">"; //$NON-NLS-1$ protected static final String GREATER_THAN_ENTITY = ">"; //$NON-NLS-1$ protected static final String LESS_THAN = "<"; //$NON-NLS-1$ protected static final String LESS_THAN_ENTITY = "<"; //$NON-NLS-1$ protected static final String LF = "\n"; //$NON-NLS-1$ protected static final String LINE_FEED = "\n"; //$NON-NLS-1$ protected static final String LINE_FEED_ENTITY = "\\n"; //$NON-NLS-1$ protected static final String LINE_FEED_TAG = "<dl>"; //$NON-NLS-1$ protected static final String LINE_TAB = "\t"; //$NON-NLS-1$ protected static final String LINE_TAB_ENTITY = "\\t"; //$NON-NLS-1$ protected static final String LINE_TAB_TAG = "<dd>"; //$NON-NLS-1$ protected static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$ protected static final char SINGLE_QUOTE_CHAR = '\''; protected static final String SINGLE_QUOTE_ENTITY = "'"; //$NON-NLS-1$ protected static final String SPACE = " "; //$NON-NLS-1$ protected static final String SPACE_ENTITY = " "; //$NON-NLS-1$ /** * Convert <code>String</code>s in attribute name format (lowercase, hyphens separating words) into property name * format (camel-cased). For example, <code>transaction-manager</code> is converted into * <code>transactionManager</code>. */ public static String attributeNameToPropertyName(String attributeName) { if (attributeName.indexOf("-") == -1) { return attributeName; } char[] chars = attributeName.toCharArray(); char[] result = new char[chars.length - 1]; int currPos = 0; boolean upperCaseNext = false; for (char c : chars) { if (c == '-') { upperCaseNext = true; continue; } else if (upperCaseNext) { result[currPos++] = Character.toUpperCase(c); upperCaseNext = false; } else { result[currPos++] = c; } } return new String(result, 0, currPos); } public static String convertToHTMLContent(String content) { content = replace(content, AMPERSTAND, AMPERSTAND_ENTITY); content = replace(content, LESS_THAN, LESS_THAN_ENTITY); content = replace(content, GREATER_THAN, GREATER_THAN_ENTITY); content = replace(content, LINE_FEED, LINE_FEED_TAG); content = replace(content, LINE_TAB, LINE_TAB_TAG); content = replace(content, SINGLE_QUOTE, SINGLE_QUOTE_ENTITY); content = replace(content, DOUBLE_QUOTE, DOUBLE_QUOTE_ENTITY); content = replace(content, SPACE + SPACE, SPACE_ENTITY + SPACE_ENTITY); // replacing return content; } public static final String createAdditionalProposalInfo(IBean bean) { StringBuffer buf = new StringBuffer(); buf.append("<b>id:</b> "); buf.append(bean.getElementName()); if (bean.getAliases() != null && bean.getAliases().length > 0) { buf.append("<br><b>alias:</b> "); for (int i = 0; i < bean.getAliases().length; i++) { buf.append(bean.getAliases()[i]); if (i < bean.getAliases().length - 1) { buf.append(", "); } } } buf.append("<br><b>class:</b> "); buf.append(bean.getClassName()); buf.append("<br><b>singleton:</b> "); buf.append(bean.isSingleton()); buf.append("<br><b>abstract:</b> "); buf.append(bean.isAbstract()); buf.append("<br><b>lazy-init:</b> "); buf.append(bean.isLazyInit()); buf.append("<br><b>filename:</b> "); buf.append(bean.getElementResource().getProjectRelativePath()); return buf.toString(); } public static final String createAdditionalProposalInfo(Node bean, IFile file) { NamedNodeMap attributes = bean.getAttributes(); StringBuffer buf = new StringBuffer(); buf.append("<b>id:</b> "); if (attributes.getNamedItem("id") != null) { buf.append(attributes.getNamedItem("id").getNodeValue()); } if (attributes.getNamedItem("name") != null) { buf.append("<br><b>alias:</b> "); buf.append(attributes.getNamedItem("name").getNodeValue()); } buf.append("<br><b>class:</b> "); if (attributes.getNamedItem("class") != null) { buf.append(attributes.getNamedItem("class").getNodeValue()); } buf.append("<br><b>singleton:</b> "); if (attributes.getNamedItem("singleton") != null) { buf.append(attributes.getNamedItem("singleton").getNodeValue()); } else { buf.append("true"); } buf.append("<br><b>abstract:</b> "); if (attributes.getNamedItem("abstract") != null) { buf.append(attributes.getNamedItem("abstract").getNodeValue()); } else { buf.append("false"); } buf.append("<br><b>lazy-init:</b> "); if (attributes.getNamedItem("lazy-init") != null) { buf.append(attributes.getNamedItem("lazy-init").getNodeValue()); } else { buf.append("default"); } if (file != null) { buf.append("<br><b>filename:</b> "); buf.append(file.getProjectRelativePath()); } return buf.toString(); } public static final String createAdditionalProposalInfo(Object obj, IProgressMonitor monitor) { if (obj instanceof IBean) { return createAdditionalProposalInfo((IBean) obj); } else if (obj instanceof ElementImpl) { ElementImpl node = (ElementImpl) obj; IStructuredDocument document = node.getStructuredDocument(); IFile resource = getFile(document); return createAdditionalProposalInfo((Node) obj, resource); } else if (obj instanceof IMember) { return new ProposalInfo((IMember) obj).getInfo(monitor); } return null; } public static final void extractAllMethodsFromPropertyPathElements(List propertyPath, List types, IFile file, int counter, List<IMethod> methods) { IMethod method = null; if (propertyPath != null && propertyPath.size() > 0) { if (propertyPath.size() > (counter + 1)) { if (types != null) { IType returnType = null; for (int i = 0; i < types.size(); i++) { IType type = (IType) types.get(i); try { IMethod getMethod = Introspector.getReadableProperty(type, (String) propertyPath.get(counter)); returnType = JdtUtils.getJavaTypeForMethodReturnType(getMethod, type); methods.add(getMethod); } catch (JavaModelException e) { } } if (returnType != null) { List<IType> newTypes = new ArrayList<IType>(); newTypes.add(returnType); extractAllMethodsFromPropertyPathElements(propertyPath, newTypes, file, (counter + 1), methods); } } } else { for (int i = 0; i < types.size(); i++) { IType type = (IType) types.get(i); try { method = Introspector.getWritableProperty(type, (String) propertyPath.get(counter)); methods.add(method); } catch (JavaModelException e) { } } } } } public static final IMethod extractMethodFromPropertyPathElements(List propertyPathElements, List types, IFile file, int counter) { IMethod method = null; if (propertyPathElements != null && propertyPathElements.size() > 0) { if (propertyPathElements.size() > (counter + 1)) { if (types != null) { IType returnType = null; for (int i = 0; i < types.size(); i++) { IType type = (IType) types.get(i); String propertyPath = (String) propertyPathElements.get(counter); try { IMethod getMethod = Introspector.getReadableProperty(type, PropertyAccessorUtils.getPropertyName(propertyPath)); returnType = JdtUtils.getJavaTypeForMethodReturnType(getMethod, type); } catch (JavaModelException e) { } } if (returnType != null) { List<IType> newTypes = new ArrayList<IType>(); newTypes.add(returnType); method = extractMethodFromPropertyPathElements(propertyPathElements, newTypes, file, (counter + 1)); } } } else { for (int i = 0; i < types.size(); i++) { IType type = (IType) types.get(i); String propertyPath = (String) propertyPathElements.get(counter); try { method = Introspector.getWritableProperty(type, PropertyAccessorUtils.getPropertyName(propertyPath)); } catch (JavaModelException e) { } } } } return method; } public static final IRegion extractPropertyPathFromCursorPosition(IRegion hyperlinkRegion, IRegion cursor, String target, List<String> propertyPaths) { int cursorIndexInTarget = cursor.getOffset() - hyperlinkRegion.getOffset(); if (cursorIndexInTarget > 0 && cursorIndexInTarget < target.length()) { String preTarget = target.substring(0, cursorIndexInTarget); if (!preTarget.endsWith(PropertyAccessor.NESTED_PROPERTY_SEPARATOR)) { int regionOffset = hyperlinkRegion.getOffset() + preTarget.lastIndexOf(PropertyAccessor.NESTED_PROPERTY_SEPARATOR) + 1; int segmentCount = new StringTokenizer(preTarget, PropertyAccessor.NESTED_PROPERTY_SEPARATOR) .countTokens(); StringTokenizer tok = new StringTokenizer(target, PropertyAccessor.NESTED_PROPERTY_SEPARATOR); for (int i = 0; i < segmentCount; i++) { propertyPaths.add(tok.nextToken()); } int regionLength = (propertyPaths.get(segmentCount - 1)).length(); return new Region(regionOffset, regionLength); } } return hyperlinkRegion; } /** * Returns the attribute from given node at specified offset. */ public static final Attr getAttrByOffset(Node node, int offset) { if ((node instanceof IndexedRegion) && ((IndexedRegion) node).contains(offset) && (node.hasAttributes())) { NamedNodeMap attrs = node.getAttributes(); // go through each attribute in node and if attribute contains // offset, return that attribute for (int i = 0; i < attrs.getLength(); ++i) { // assumption that if parent node is of type IndexedRegion, // then its attributes will also be of type IndexedRegion IndexedRegion attRegion = (IndexedRegion) attrs.item(i); if (attRegion.contains(offset)) { return (Attr) attrs.item(i); } } } return null; } public static final boolean isElementAtOffset(Node node, int offset) { IndexedRegion region = ((IndexedRegion) node); int nameLength = node.getNodeName().length(); return (region.getStartOffset() + nameLength) >= offset && region.getStartOffset() <= offset; } /** * /** Returns the closest IndexedRegion for the offset and viewer allowing for differences between viewer offsets * and model positions. note: this method returns an IndexedRegion for read only * <p> * Copied from {@link ContentAssistUtils} in order to solve compatibility problems on 3.2. * @see ContentAssistUtils#getNodeAt(ITextViewer, int) */ public static IndexedRegion getNodeAt(ITextViewer viewer, int documentOffset) { if (viewer == null) return null; IndexedRegion node = null; IModelManager mm = StructuredModelManager.getModelManager(); IStructuredModel model = null; if (mm != null) model = mm.getExistingModelForRead(viewer.getDocument()); try { if (model != null) { int lastOffset = documentOffset; node = model.getIndexedRegion(documentOffset); while (node == null && lastOffset >= 0) { lastOffset--; node = model.getIndexedRegion(lastOffset); } } } finally { if (model != null) model.releaseFromRead(); } return node; } public static final String getAttribute(Node node, String attributeName) { if (hasAttribute(node, attributeName)) { return node.getAttributes().getNamedItem(attributeName).getNodeValue(); } return null; } public static final Set<IBean> getBeansFromConfigSets(IFile file) { Set<IBean> beans = new HashSet<IBean>(); Set<IBeansConfig> configs = new HashSet<IBeansConfig>(); if (file != null && file.exists()) { IBeansProject project = BeansCorePlugin.getModel().getProject(file.getProject()); Set<IBeansConfig> allConfigs = BeansCorePlugin.getModel().getConfigs(file, true); for (IBeansConfig config : allConfigs) { if (config instanceof IImportedBeansConfig) { IBeansConfig rootBeansConfig = BeansModelUtils.getParentOfClass(config, IBeansConfig.class); configs.add(rootBeansConfig); } } if (project != null) { Set<IBeansConfigSet> configSets = project.getConfigSets(); for (IBeansConfigSet configSet : configSets) { if (configSet.hasConfig(file) || !BeansCoreUtils.isBeansConfig(file)) { Set<IBeansConfig> bcs = configSet.getConfigs(); configs.addAll(bcs); } Set<IBeansConfig> tempConfigs = new HashSet<IBeansConfig>(configs); for (IBeansConfig config : tempConfigs) { if (configSet.hasConfig(config.getElementName())) { Set<IBeansConfig> bcs = configSet.getConfigs(); configs.addAll(bcs); } } } } if (BeansCoreUtils.isBeansConfig(file, true)) { IBeansConfig config = BeansCorePlugin.getModel().getConfig(file); if (config instanceof IImportedBeansConfig) { configs.add(BeansModelUtils.getParentOfClass(config, IBeansConfig.class)); } else { configs.add(config); } } for (IBeansConfig bc : configs) { Set<IBean> bs = bc.getBeans(); for (IBean b : bs) { if (!b.getElementResource().equals(file)) { beans.add(b); } } Set<IBeansComponent> components = bc.getComponents(); for (IBeansComponent component : components) { getBeansFromComponent(file, component, beans); } } } return beans; } private static void getBeansFromComponent(IFile file, IBeansComponent component, Set<IBean> beansAcc) { Set<IBean> bs = component.getBeans(); for (IBean b : bs) { if (!b.getElementResource().equals(file)) { beansAcc.add(b); } } Set<IBeansComponent> childComponents = component.getComponents(); for (IBeansComponent childComponent : childComponents) { getBeansFromComponent(file, childComponent, beansAcc); } } public static final String getClassNameForBean(IFile file, Document document, Node node) { NamedNodeMap attributes = node.getAttributes(); String className = (attributes.getNamedItem("class") != null ? attributes.getNamedItem("class").getNodeValue() : null); String factoryMethod = (attributes.getNamedItem("factory-method") != null ? attributes.getNamedItem( "factory-method").getNodeValue() : null); String factoryBean = (attributes.getNamedItem("factory-bean") != null ? attributes.getNamedItem("factory-bean") .getNodeValue() : null); if (!org.springframework.util.StringUtils.hasText(factoryBean)) { factoryBean = (attributes.getNamedItem("factory-ref") != null ? attributes.getNamedItem("factory-ref") .getNodeValue() : null); } String parent = (attributes.getNamedItem("parent") != null ? attributes.getNamedItem("parent").getNodeValue() : null); if (factoryBean == null && factoryMethod == null && parent == null) { return className; } else if (className != null && factoryMethod != null && factoryBean == null && file != null) { // Factory method on bean class return resolveClassNameFromFactoryMethod(factoryMethod, className, file.getProject()); } else if (factoryMethod != null && factoryBean != null && file != null) { // Factory method on factory bean String factoryClass = getClassNameForBean(file, document, factoryBean); if (factoryClass != null && file != null) { return resolveClassNameFromFactoryMethod(factoryMethod, factoryClass, file.getProject()); } return null; } else if (className == null && parent != null) { return getClassNameForBean(file, document, parent); } else if (className != null) { return className; } return null; } public static final String getClassNameForBean(IFile file, Document document, String id) { boolean foundLocal = false; NodeList beanNodes = document.getElementsByTagNameNS(NamespaceUtils.DEFAULT_NAMESPACE_URI, "bean"); for (int i = 0; i < beanNodes.getLength(); i++) { Node beanNode = beanNodes.item(i); NamedNodeMap attributes = beanNode.getAttributes(); if (attributes.getNamedItem("id") != null) { String idTemp = (attributes.getNamedItem("id") != null ? attributes.getNamedItem("id").getNodeValue() : null); if (id != null && id.equals(idTemp)) { return getClassNameForBean(file, document, beanNode); } } } if (!foundLocal) { Set<IBean> beansList = BeansEditorUtils.getBeansFromConfigSets(file); Iterator<IBean> iterator = beansList.iterator(); while (iterator.hasNext()) { IBean bean = iterator.next(); if (id != null && id.equals(bean.getElementName())) { return BeansModelUtils.getBeanClass(bean, null); } } } // if we reach this point we haven't found a class name. so try to // locate the xml element // and calculate the class from there Element node = document.getElementById(id); if (node != null && node.getNamespaceURI() != null && NamespaceUtils.getClassNameProvider(node.getNamespaceURI()).length > 0) { for (IClassNameProvider provider : NamespaceUtils.getClassNameProvider(node.getNamespaceURI())) { String className = provider.getClassNameForElement(node); if (className != null) { return className; } } } return null; } public static String getClassNameForBean(Node bean) { return getAttribute(bean, "class"); } public static final List<IType> getClassNamesOfBean(IFile file, Node node) { List<IType> classNames = new ArrayList<IType>(); NamedNodeMap rootAttributes = node.getAttributes(); String id = (rootAttributes.getNamedItem("id") != null ? rootAttributes.getNamedItem("id").getNodeValue() : null); if (id == null) { id = node.toString(); } String className = (rootAttributes.getNamedItem("class") != null ? rootAttributes.getNamedItem("class") .getNodeValue() : null); String parentId = (rootAttributes.getNamedItem("parent") != null ? rootAttributes.getNamedItem("parent") .getNodeValue() : null); getClassNamesOfBeans(file, node.getOwnerDocument(), id, className, parentId, classNames, new ArrayList<String>()); return classNames; } private static final void getClassNamesOfBeans(IFile file, Document document, String id, String className, String parentId, List<IType> classNames, List<String> beans) { // detect cicular dependencies if (id != null) { if (beans.contains(id)) { return; } else { beans.add(id); } } else { return; } if (className != null && file != null) { IType type = JdtUtils.getJavaType(file.getProject(), className); if (type != null && !classNames.contains(type)) { classNames.add(type); } } if (parentId != null) { boolean foundLocal = false; NodeList beanNodes = document.getElementsByTagName("bean"); for (int i = 0; i < beanNodes.getLength(); i++) { Node beanNode = beanNodes.item(i); NamedNodeMap attributes = beanNode.getAttributes(); if (attributes.getNamedItem("id") != null) { String idTemp = (attributes.getNamedItem("id") != null ? attributes.getNamedItem("id") .getNodeValue() : null); String classNameTemp = (attributes.getNamedItem("class") != null ? attributes.getNamedItem("class") .getNodeValue() : null); String parentIdTemp = (attributes.getNamedItem("parent") != null ? attributes .getNamedItem("parent").getNodeValue() : null); if (parentId.equals(idTemp)) { foundLocal = true; getClassNamesOfBeans(file, document, idTemp, classNameTemp, parentIdTemp, classNames, beans); } } } if (!foundLocal) { Set<IBean> beansList = BeansEditorUtils.getBeansFromConfigSets(file); Iterator<IBean> iterator = beansList.iterator(); while (iterator.hasNext()) { IBean bean = iterator.next(); if (parentId.equals(bean.getElementName())) { getClassNamesOfBeans(file, document, bean.getElementName(), BeansModelUtils.getBeanClass(bean, null), bean.getParentName(), classNames, beans); break; } } } } } public static IFile getFile(ContentAssistRequest request) { IResource resource = null; String baselocation = null; if (request != null) { IStructuredDocumentRegion region = request.getDocumentRegion(); if (region != null) { IDocument document = region.getParentDocument(); IStructuredModel model = null; try { model = org.eclipse.wst.sse.core.StructuredModelManager.getModelManager().getExistingModelForRead( document); if (model != null) { baselocation = model.getBaseLocation(); } } finally { if (model != null) { model.releaseFromRead(); } } } } if (baselocation != null) { // copied from JSPTranslationAdapter#getJavaProject IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IPath filePath = new Path(baselocation); if (filePath.segmentCount() > 0) { resource = root.getFile(filePath); } } return (IFile) resource; } /** * Returns the file the given document was read from. */ public static final IFile getFile(IDocument document) { IFile resource = null; String baselocation = null; if (document != null) { IStructuredModel model = null; try { model = org.eclipse.wst.sse.core.StructuredModelManager.getModelManager().getExistingModelForRead( document); if (model != null) { baselocation = model.getBaseLocation(); } } finally { if (model != null) { model.releaseFromRead(); } } } IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); if (baselocation != null) { IPath path = new Path(baselocation); if (root.exists(path) && path.segmentCount() > 1) { resource = root.getFile(path); } else { // This is a fallback for XML stored in a jar or zip files IEditorPart editor = SpringUIUtils.getActiveEditor(); IEditorInput input = editor.getEditorInput(); if (input instanceof IFileEditorInput) { resource = ((IFileEditorInput) input).getFile(); } else if (input instanceof ZipEntryEditorInput) { resource = (IFile) ((ZipEntryEditorInput) input).getAdapter(IFile.class); } else if (input instanceof JarEntryEditorInput) { JarEntryFile jarFile = (JarEntryFile) ((JarEntryEditorInput) input).getStorage(); IPackageFragmentRoot jarPackageFragmentRoot = jarFile.getPackageFragmentRoot(); resource = jarPackageFragmentRoot.getJavaProject().getProject().getFile(".project"); } } } return resource; } public static final Node getFirstReferenceableNodeById(Document document, String id, IFile file) { Map<String, Node> nodes = getReferenceableNodes(document, file); for (Entry<String, Node> node : nodes.entrySet()) { if (node.getKey().equals(id)) { return node.getValue(); } } return null; } public static final List<Node> getReferenceableNodesById(Document document, String id, IFile file) { List<Node> nodes = new ArrayList<Node>(); for (IReferenceableElementsLocator locator : NamespaceUtils.getAllElementsLocators()) { Map<String, Set<Node>> tempNodess = locator.getReferenceableElements(document, file); if (tempNodess != null) { for(String name: tempNodess.keySet()) { if (name.equals(id)) { Set<Node> tempNodes = tempNodess.get(name); for(Node tempNode: tempNodes) { updateList(tempNode, nodes); } } } } } return nodes; } /** * Add newNode to nodes if it is not already in the list of nodes * @param newNode * @param nodes */ private static void updateList(Node newNode, List<Node> nodes) { IDOMNode domNewNode = (IDOMNode) newNode; boolean found = false; for(Node node: nodes) { if (newNode.getOwnerDocument().equals(node.getOwnerDocument())) { IDOMNode domNode = (IDOMNode) node; if (domNode.getStartOffset() == domNewNode.getStartOffset() && domNode.getEndOffset() == domNewNode.getEndOffset()) { found = true; } } } if (!found) { nodes.add(newNode); } } /** * Returns the node from given document at specified offset. * @param offset the offset with given document * @return Node either element, doctype, text, or null */ public static final Node getNodeByOffset(IDocument document, int offset) { // get the node at offset (returns either: element, doctype, text) IndexedRegion inode = null; IStructuredModel sModel = null; try { sModel = org.eclipse.wst.sse.core.StructuredModelManager.getModelManager() .getExistingModelForRead(document); if (sModel == null && document instanceof IStructuredDocument) { sModel = org.eclipse.wst.sse.core.StructuredModelManager.getModelManager().getModelForRead( (IStructuredDocument) document); } inode = sModel.getIndexedRegion(offset); if (inode == null) { inode = sModel.getIndexedRegion(offset - 1); } } finally { if (sModel != null) { sModel.releaseFromRead(); } } if (inode instanceof Node) { return (Node) inode; } return null; } /** * Returns the non-blocking Progress Monitor form the StatuslineManger * @return the progress monitor */ public static final IProgressMonitor getProgressMonitor() { IWorkbenchWindow activeWorkbenchWindow = Activator.getActiveWorkbenchWindow(); // this check is to allow for non UI thread call to this method if (activeWorkbenchWindow == null) { return new NullProgressMonitor(); } IEditorPart editor = activeWorkbenchWindow.getActivePage().getActiveEditor(); if (editor != null && editor.getEditorSite() != null && editor.getEditorSite().getActionBars() != null && editor.getEditorSite().getActionBars().getStatusLineManager() != null && editor.getEditorSite().getActionBars().getStatusLineManager().getProgressMonitor() != null) { IStatusLineManager manager = editor.getEditorSite().getActionBars().getStatusLineManager(); IProgressMonitor monitor = manager.getProgressMonitor(); manager.setMessage("Processing completion proposals"); manager.setCancelEnabled(true); return monitor; } else { return new NullProgressMonitor(); } } public static final IProject getProject(IDocument document) { IProject project = null; IEditorInput input = Workbench.getInstance().getActiveWorkbenchWindow().getActivePage().getActiveEditor() .getEditorInput(); if (input instanceof ZipEntryEditorInput) { ZipEntryStorage storage = (ZipEntryStorage) ((ZipEntryEditorInput) input).getStorage(); project = storage.getFile().getProject(); } else { IFile file = BeansEditorUtils.getFile(document); project = file.getProject(); } return project; } public static final Map<String, Node> getReferenceableNodes(Document document, IFile file) { Map<String, Node> nodes = new HashMap<String, Node>(); for (IReferenceableElementsLocator locator : NamespaceUtils.getAllElementsLocators()) { Map<String, Set<Node>> tempNodes = locator.getReferenceableElements(document, file); if (tempNodes != null) { for(String name: tempNodes.keySet()) { Set<Node> set = tempNodes.get(name); if (set != null && set.size() > 0) { Node node = set.iterator().next(); if (node == null) { Activator.log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Null entry in the set of referencable nodes. Name: '" + name + "'. Locator class: " + locator.getClass().getName())); } else { nodes.put(name, node); } } } } } return nodes; } public static final boolean hasAttribute(Node node, String attributeName) { return (node != null && node.hasAttributes() && node.getAttributes().getNamedItem(attributeName) != null); } public static final boolean isSpringStyleOutline() { return Activator.getDefault().getPreferenceStore().getBoolean(IPreferencesConstants.OUTLINE_SPRING); } public static final String propertyNameToAttributeName(String propertyName) { char[] chars = propertyName.toCharArray(); StringBuffer buf = new StringBuffer(); for (char c : chars) { if (Character.isUpperCase(c)) { c = Character.toLowerCase(c); buf.append('-'); buf.append(c); } else { buf.append(c); } } return buf.toString(); } /** * Replace matching literal portions of a string with another string */ public static final String replace(String aString, String source, String target) { if (aString == null) { return null; } String normalString = ""; //$NON-NLS-1$ int length = aString.length(); int position = 0; int previous = 0; int spacer = source.length(); while (position + spacer - 1 < length && aString.indexOf(source, position) > -1) { position = aString.indexOf(source, previous); normalString = normalString + aString.substring(previous, position) + target; position += spacer; previous = position; } normalString = normalString + aString.substring(position, aString.length()); return normalString; } private static String resolveClassNameFromFactoryMethod(String factoryMethod, String className, IProject project) { IType type = JdtUtils.getJavaType(project, className); if (type != null) { try { Set<IMethod> methods = Introspector.getAllMethods(type); for (IMethod m : methods) { if (m.getElementName().equals(factoryMethod)) { return JdtUtils.resolveClassNameBySignature(m.getReturnType(), type); } } } catch (JavaModelException e) { } } return null; } public static String prepareMatchString(ContentAssistRequest request) { String matchString = request.getMatchString(); return prepareMatchString(matchString); } public static String prepareMatchString(String matchString) { if (matchString == null) { matchString = ""; } if (matchString.length() > 0 && (matchString.startsWith("\"") || matchString.startsWith("'"))) { matchString = matchString.substring(1); } return matchString; } }