/******************************************************************************* * Copyright (c) 2008, 2010 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 * * Provisional API: This class/interface is part of an interim API that is still under development and expected to * change significantly before reaching stability. It is being made available at this early stage to solicit feedback * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken * (repeatedly) as the API evolves. * * *******************************************************************************/ package org.eclipse.wst.jsdt.web.core.javascript; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.wst.jsdt.core.IJavaScriptProject; import org.eclipse.wst.jsdt.core.JavaScriptCore; import org.eclipse.wst.jsdt.web.core.internal.Logger; 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.xml.core.internal.provisional.document.IDOMModel; /** * * Provisional API: This class/interface is part of an interim API that is still under development and expected to * change significantly before reaching stability. It is being made available at this early stage to solicit feedback * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken * (repeatedly) as the API evolves. * <br><br> this adapter loads translation information from extension points. this is to allow more complicated html/js translations through extensions. * @author pavery */ public class JsTranslationAdapter implements INodeAdapter, IResourceChangeListener { private static final boolean DEBUG = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jstranslation")); //$NON-NLS-1$ //$NON-NLS-2$ private IStructuredDocument fHtmlDocument = null; private IJsTranslation fJSTranslation = null; private NullProgressMonitor fTranslationMonitor = null; private String baseLocation; private boolean listenForChanges=false; private static final String PRIORITY_ATTRIB = "priority"; private IJsTranslation fTranslationAsFactory; public JsTranslationAdapter(IDOMModel xmlModel) { fHtmlDocument = xmlModel.getStructuredDocument(); baseLocation = xmlModel.getBaseLocation(); initializeJavaPlugins(); } public void shouldListenForChanges(boolean listenForProjectChanges) { if(listenForProjectChanges) { ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); } } public IJavaScriptProject getJavaProject() { IJavaScriptProject javaProject = null; IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IPath filePath = new Path(baseLocation); IProject project = null; if (filePath.segmentCount() > 0) { project = root.getProject(filePath.segment(0)); } if (project != null) { javaProject = JavaScriptCore.create(project); } return javaProject; } /** * Returns the IJsTranslation for this adapter. * * @return a IJsTranslation */ public IJsTranslation getJsTranslation(boolean listenForChanges) { /* * If no translation exists or switching from not listening to * listening */ if (fJSTranslation == null || (!this.listenForChanges && listenForChanges)) { if (fJSTranslation != null) fJSTranslation.release(); if (fTranslationAsFactory == null) { /* load the translation factory from the extension point */ try { IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint extensionPoint = registry.getExtensionPoint("org.eclipse.wst.jsdt.web.core.javascriptPreProcessor"); IConfigurationElement points[] = extensionPoint.getConfigurationElements(); int highestPriorityValue = -1; int highestPriorityIndex = -1; for (int i = 0; i < points.length; i++) { String priority = points[i].getAttribute(PRIORITY_ATTRIB); int value = Integer.parseInt(priority); if (value > highestPriorityValue) { highestPriorityIndex = i; highestPriorityValue = value; } } fTranslationAsFactory = (IJsTranslation) points[highestPriorityIndex].createExecutableExtension("class"); } catch (Exception e) { Logger.logException(e); } } if (fTranslationAsFactory != null) { fJSTranslation = fTranslationAsFactory.getInstance(fHtmlDocument, getJavaProject(), listenForChanges); } else { fJSTranslation = new JsTranslation(fHtmlDocument, getJavaProject(), listenForChanges); } this.listenForChanges = listenForChanges; } shouldListenForChanges(listenForChanges); return fJSTranslation; } private void initializeJavaPlugins() { JavaScriptCore.getPlugin(); } public boolean isAdapterForType(Object type) { return type.equals(IJsTranslation.class); } public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {} public void release() { if (fTranslationMonitor != null) { fTranslationMonitor.setCanceled(true); } ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); if (fJSTranslation != null) { if (JsTranslationAdapter.DEBUG) { System.out.println("JSTranslationAdapter releasing:" + fJSTranslation); //$NON-NLS-1$ } fJSTranslation.release(); } } /* (non-Javadoc) * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) */ public void resourceChanged(IResourceChangeEvent event) { IProject changedProject = (event==null || event.getResource()==null)?null:event.getResource().getProject(); if(changedProject!=null && getJavaProject().getProject().equals(changedProject) && fJSTranslation!=null){ fJSTranslation.classpathChange(); } } }