/*******************************************************************************
* 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.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.zip.ZipFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.pde.internal.ui.editor.JarEntryEditorInput;
import org.eclipse.pde.internal.ui.editor.JarEntryFile;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.editors.text.ILocationProvider;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.jboss.tools.common.text.ext.ExtensionsPlugin;
import org.jboss.tools.common.text.ext.hyperlink.AbstractHyperlink;
import org.jboss.tools.common.text.ext.hyperlink.xpl.Messages;
import org.jboss.tools.common.text.ext.util.Utils;
/**
* @author Jeremy
*/
public class XMLXmlNsHyperlink extends AbstractHyperlink {
class StorageEditorInput extends PlatformObject implements IStorageEditorInput, IStorage, ILocationProvider {
private File fFile;
public StorageEditorInput(File file) {
fFile = file;
}
public IStorage getStorage() {
return (fFile == null ? null : this);
}
public ImageDescriptor getImageDescriptor() {
return null;
}
public String getName() {
return fFile.getName();
}
public IPersistableElement getPersistable() {
return null;
}
public String getToolTipText() {
return getFullPath().toOSString();
}
/*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof StorageEditorInput) {
StorageEditorInput input = (StorageEditorInput) o;
return fFile.equals(input.fFile);
}
return false;
}
public int hashCode() {
return fFile.hashCode();
}
public boolean exists() {
return fFile.exists();
}
public InputStream getContents() throws CoreException {
try {
return new FileInputStream(fFile);
} catch (FileNotFoundException x) {
//ignore
return null;
}
}
public IPath getFullPath() {
return new Path (fFile.getAbsolutePath());
}
public boolean isReadOnly() {
return !fFile.canWrite();
}
public IPath getPath(Object element) {
if (element instanceof StorageEditorInput) {
return new Path(((StorageEditorInput)element).fFile.getAbsolutePath());
}
return null;
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.sse.editor.AbstractHyperlink#doHyperlink(org.eclipse.jface.text.IRegion)
*/
protected void doHyperlink(IRegion region) {
try {
String mappedSystemId = getMappedSystemIdFromCatalog(getPublicId(region), getSystemId(region));
String filename = getFilenameFromMappedSystemId(mappedSystemId);
IEditorPart part = null;
if (filename != null) {
part = openExternalFile(filename);
if (part == null)
openFileFailed();
} else if (mappedSystemId != null) {
openFileInEditor(mappedSystemId);
} else {
String uri = getURI(region);
if (uri != null && uri.toLowerCase().startsWith("http:")) { //$NON-NLS-1$
URL url = null;
url = new URL(uri);
IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench().getBrowserSupport();
IWebBrowser browser = browserSupport.createBrowser(IWorkbenchBrowserSupport.LOCATION_BAR | IWorkbenchBrowserSupport.NAVIGATION_BAR, null, null, null);
browser.openURL(url);
} else {
openFileFailed();
}
}
} catch (MalformedURLException x) {
// could not open editor
openFileFailed();
} catch (PartInitException x) {
openFileFailed();
}
}
/**
* Try to open the external file, fileString in its default editor
* @param fileString
* @return IEditorPart editor opened or null if editor could not be opened
*/
protected IEditorPart openExternalFile(String fileString) {
// file does not exist in workspace so try to open using system editor
File file = new File(fileString);
if (!file.exists())
return null;
IEditorInput input = new StorageEditorInput(file);
String editorId = getEditorId(fileString);
try {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
return page.openEditor(input, editorId, true);
}
catch (PartInitException pie) {
ExtensionsPlugin.getPluginLog().logError(pie);
}
return null;
}
protected final String JAR_FILE_PROTOCOL = "jar:file:/";//$NON-NLS-1$
protected final String JAR_FILE = "jar:file:";//$NON-NLS-1$
private int taglibLength;
private int taglibOffset;
/* (non-Javadoc)
* @see com.ibm.sse.editor.hyperlink.AbstractHyperlink#openFileInEditor(java.lang.String)
*/
protected void openFileInEditor(String fileString) {
if (fileString.startsWith(JAR_FILE_PROTOCOL)) {
fileString = fileString.substring(JAR_FILE_PROTOCOL.length());
IEditorInput jarEditorInput = createEditorInput(fileString);
IEditorPart part = openFileInEditor(jarEditorInput, fileString);
if (part == null) openFileFailed();
} else if (fileString.startsWith(JAR_FILE)) {
fileString = fileString.substring(JAR_FILE.length());
IEditorInput jarEditorInput = createEditorInputAlternate(fileString);
IEditorPart part = openFileInEditor(jarEditorInput, fileString);
if (part == null) openFileFailed();
} else {
super.openFileInEditor(fileString);
}
}
protected IEditorInput createEditorInputAlternate(String fileString) {
String jarName = fileString.substring(0,fileString.indexOf("!")); //$NON-NLS-1$
String entryName = fileString.substring(fileString.indexOf("!")+2,fileString.length()); //$NON-NLS-1$
ZipFile jarFile = null;
try {
jarFile = new ZipFile(jarName);
} catch (IOException e) {
return null;
}
JarEntryFile jarEntryFile = new JarEntryFile(jarFile, entryName);
JarEntryEditorInput jarEditorInput = new JarEntryEditorInput(jarEntryFile) {
public boolean equals(Object arg) {
return this.toString().equals(arg.toString());
}
};
return jarEditorInput;
}
String getURI(IRegion region) {
try {
return Utils.trimQuotes(getDocument().get(region.getOffset(), region.getLength()));
} catch (BadLocationException x) {
// Ignore
return null;
}
}
protected String getPublicId(IRegion region) {
String text = getURI(region);
if (text == null) return null;
int spacer = text.indexOf(" "); //$NON-NLS-1$
if (spacer == -1) spacer = text.indexOf("\t"); //$NON-NLS-1$
return (spacer == -1 ? text : text.substring(0, spacer));
}
protected String getSystemId(IRegion region) {
String text = getURI(region);
if (text == null) return null;
int spacer = text.indexOf(" "); //$NON-NLS-1$
if (spacer == -1) spacer = text.indexOf("\t"); //$NON-NLS-1$
if (spacer == -1) spacer = 0;
return text.substring(spacer).trim();
}
private String getMappedSystemIdFromCatalog(String publicId, String systemId) {
String mappedSystemId = null;
try {
if (publicId != null)
mappedSystemId = XMLCorePlugin.getDefault().getDefaultXMLCatalog().resolvePublic(publicId, systemId);
if (mappedSystemId == null)
mappedSystemId = XMLCorePlugin.getDefault().getDefaultXMLCatalog().resolveSystem(systemId);
if (mappedSystemId == null && systemId != null)
mappedSystemId = XMLCorePlugin.getDefault().getDefaultXMLCatalog().resolveURI(systemId);
} catch (IOException e) {
// Ignore
return null;
}
return mappedSystemId;
}
private String getFilenameFromMappedSystemId(String mappedSystemId) {
String fileName = null;
try {
if(mappedSystemId!=null) {
File file = new File(new URL(mappedSystemId).getFile());
if(file.isFile()) {
fileName = file.getAbsolutePath();
}
}
} catch (MalformedURLException x) {
// Ignore
return null;
}
return fileName;
}
/*
* (non-Javadoc)
*
* @see IHyperlink#getHyperlinkText()
*/
public String getHyperlinkText() {
String uri = getURI(getHyperlinkRegion());
if (uri == null)
return MessageFormat.format(Messages.NotFound, "URI"); //$NON-NLS-1$
return MessageFormat.format(Messages.Open, uri);
}
}