/******************************************************************************* * Copyright (c) 2007-2012 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.text.ext.hyperlink; import java.util.Arrays; import java.util.Comparator; import org.eclipse.core.internal.resources.ICoreConstants; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.internal.core.JarEntryFile; import org.eclipse.jdt.internal.ui.javaeditor.JarEntryEditorInput; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.ui.IEditorInput; import org.eclipse.wst.common.componentcore.internal.ComponentResource; import org.eclipse.wst.common.componentcore.internal.StructureEdit; import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.jboss.tools.common.el.core.GlobalELReferenceList; import org.jboss.tools.common.model.XModel; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.project.IModelNature; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.resref.core.ResourceReference; import org.jboss.tools.common.text.ext.hyperlink.xpl.AbstractBaseHyperlink; import org.jboss.tools.common.text.ext.util.StructuredModelWrapper; import org.jboss.tools.common.text.ext.util.Utils; /** * */ @SuppressWarnings("restriction") abstract public class AbstractHyperlink extends AbstractBaseHyperlink implements IHyperlink { public static final String DOLLAR_PREFIX = "${"; //$NON-NLS-1$ private static final String SUFFIX = "}"; //$NON-NLS-1$ public static final String SHARP_PREFIX = "#{"; //$NON-NLS-1$ public static XModel getXModel(IFile file) { if (file == null) return null; XModelObject fs = EclipseResourceUtil.getObjectByResource(file); if (fs != null) return fs.getModel(); fs = EclipseResourceUtil.createObjectForResource(file); if (fs != null) return fs.getModel(); IProject project = file.getProject(); IModelNature nature = EclipseResourceUtil.getModelNature(project); return (nature == null) ? null : nature.getModel(); } protected IFile getFile() { StructuredModelWrapper smw = new StructuredModelWrapper(); try { smw.init(getDocument()); return smw.getFile(); } finally { smw.dispose(); } } protected String getBaseLocation() { StructuredModelWrapper smw = new StructuredModelWrapper(); try { smw.init(getDocument()); return smw.getBaseLocation(); } finally { smw.dispose(); } } protected XModel getXModel() { StructuredModelWrapper smw = new StructuredModelWrapper(); try { smw.init(getDocument()); return smw.getXModel(); } finally { smw.dispose(); } } public static XModel getXModel(IStructuredModel structuredModel) { IFile f = getFile(structuredModel); if (f != null) return getXModel(f); if (structuredModel == null) return null; String wsRelativePath = structuredModel.getBaseLocation(); if (wsRelativePath == null) return null; if (wsRelativePath.startsWith("/")) { //$NON-NLS-1$ while (true) { int i = wsRelativePath.lastIndexOf('/'); if (i < 0) return null; wsRelativePath = wsRelativePath.substring(0, i); IPath path = new Path(wsRelativePath); IResource r = ResourcesPlugin.getWorkspace().getRoot().findMember( path); if (r != null && r.exists()) { XModelObject o = EclipseResourceUtil .createObjectForResource(r); if (o != null) return o.getModel(); } } } return null; } public static String getBaseLocation(IStructuredModel structuredModel) { if (structuredModel == null) { return null; } return structuredModel.getBaseLocation(); } public static IFile getFile(IStructuredModel structuredModel) { if (structuredModel == null) { return null; } String wsRelativePath = structuredModel.getBaseLocation(); if (wsRelativePath == null) { return null; } if (wsRelativePath.startsWith("/")) { //$NON-NLS-1$ IPath path = new Path(wsRelativePath); IResource r = ResourcesPlugin.getWorkspace().getRoot().findMember( path); if (r != null && r.exists() && r instanceof IFile) return (IFile) r; } String path = Platform.getLocation().append(wsRelativePath) .toFile().getAbsolutePath(); return EclipseResourceUtil.getFile(path); } protected IRegion doGetHyperlinkRegion(int offset) { return hyperlinkRegion; } abstract protected void doHyperlink(IRegion region); protected IFile getFileFromProject(String fileName) { IFile documentFile = getFile(); if(documentFile == null || !documentFile.isAccessible()) return null; fileName = findAndReplaceElVariable(fileName); IProject project = documentFile.getProject(); String name = Utils.trimFilePath(fileName); IPath currentPath = documentFile.getLocation() .removeLastSegments(1); IResource member = null; StructureEdit se = StructureEdit.getStructureEditForRead(project); if (se == null) { return null; } WorkbenchComponent[] modules = se.getWorkbenchModules(); for (int i = 0; i < modules.length; i++) { if (name.startsWith("/")) { //$NON-NLS-1$ member = findFileByAbsolutePath(project, modules[i], name); } else { member = findFileByRelativePath(project, modules[i], currentPath, name); if (member == null && name.length() > 0) { // in some cases path having no leading "/" is // nevertheless absolute member = findFileByAbsolutePath(project, modules[i], "/" + name); //$NON-NLS-1$ } } if (member != null && (member instanceof IFile)) { if (((IFile) member).exists()) return (IFile) member; } } return null; } // partly copied from org.jboss.tools.vpe.editor.util.ElService protected String findAndReplaceElVariable(String fileName){ final IPath workspacePath = Platform.getLocation(); final ResourceReference[] gResources = GlobalELReferenceList.getInstance().getAllResources(workspacePath); String result = fileName; ResourceReference[] sortedReferences = sortReferencesByScope(gResources); for (ResourceReference rf : sortedReferences) { final String dollarEl = DOLLAR_PREFIX + rf.getLocation() + SUFFIX; final String sharpEl = SHARP_PREFIX + rf.getLocation() + SUFFIX; if (fileName.contains(dollarEl)) { result = result.replace(dollarEl, rf.getProperties()); } if (fileName.contains(sharpEl)) { result = result.replace(sharpEl, rf.getProperties()); } } return result; } // copied from org.jboss.tools.vpe.editor.util.ElService private ResourceReference[] sortReferencesByScope(ResourceReference[] references) { ResourceReference[] sortedReferences = references.clone(); Arrays.sort(sortedReferences, new Comparator<ResourceReference>() { public int compare(ResourceReference r1, ResourceReference r2) { return r1.getScope() - r2.getScope(); } }); return sortedReferences; } private IFile findFileByRelativePath(IProject project, WorkbenchComponent module, IPath basePath, String path) { if (path == null || path.trim().length() == 0) return null; path = findAndReplaceElVariable(path); ComponentResource[] resources = module.findResourcesBySourcePath( new Path("/"), 0); //$NON-NLS-1$ IPath projectPath = project.getLocation(); IFile member = null; for (int i = 0; resources != null && i < resources.length; i++) { IPath runtimePath = resources[i].getRuntimePath(); IPath sourcePath = resources[i].getSourcePath(); // Look in source environment IPath webRootPath = projectPath.append(sourcePath); IPath relativePath = Utils.getRelativePath(webRootPath, basePath); IPath filePath = relativePath.append(path); member = project.getFile(sourcePath.append(filePath)); if (member.exists()) { return member; } // Look in runtime environment if (runtimePath.segmentCount() >= ICoreConstants.MINIMUM_FOLDER_SEGMENT_LENGTH - 1) { webRootPath = projectPath.append(runtimePath); relativePath = Utils.getRelativePath(webRootPath, basePath); filePath = relativePath.append(path); member = project.getFile(runtimePath.append(filePath)); if (member.exists()) { return member; } } } return null; } private IFile findFileByAbsolutePath(IProject project, WorkbenchComponent module, String path) { ComponentResource[] resources = module.findResourcesBySourcePath( new Path("/"), 0); //$NON-NLS-1$ path = findAndReplaceElVariable(path); IFile member = null; for (int i = 0; resources != null && i < resources.length; i++) { IPath runtimePath = resources[i].getRuntimePath(); IPath sourcePath = resources[i].getSourcePath(); // Look in source environment member = project.getFile(sourcePath.append(path)); if(member.exists()) { return member; } // Look in runtime environment if (runtimePath.segmentCount() >= ICoreConstants.MINIMUM_FOLDER_SEGMENT_LENGTH - 1) { member = project.getFile(runtimePath.append(path)); if (member.exists()) { return member; } } } return null; } protected IEditorInput createEditorInput(String fileString) { String jarName = fileString.substring(0,fileString.indexOf("!")); //$NON-NLS-1$ IFile[] fs = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(jarName)); if(fs == null || fs.length == 0) return null; IProject p = fs[0].getProject(); IJavaProject jp = EclipseResourceUtil.getJavaProject(p); if(jp == null) return null; IPackageFragmentRoot root = jp.getPackageFragmentRoot(fs[0]); String entryName = fileString.substring(fileString.indexOf("!")+2,fileString.length()); //$NON-NLS-1$ JarEntryFile f = new JarEntryFile(entryName); f.setParent(root); JarEntryEditorInput jarEditorInput = new JarEntryEditorInput(f) { public boolean equals(Object arg) { return this.toString().equals(arg.toString()); } }; return jarEditorInput; } /** * for test purpose * @return */ public IFile getReadyToOpenFile(){ return null; } }