| /******************************************************************************* |
| * Copyright (c) 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.jst.jsp.core.internal.modelquery; |
| |
| import java.util.List; |
| |
| import org.eclipse.core.resources.ProjectScope; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.jst.jsp.core.internal.JSPCorePlugin; |
| import org.eclipse.wst.sse.core.internal.ltk.modelhandler.EmbeddedTypeHandler; |
| import org.eclipse.wst.sse.core.internal.modelhandler.ModelHandlerUtility; |
| import org.eclipse.wst.sse.core.internal.provisional.IModelManager; |
| import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter; |
| import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory; |
| import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; |
| import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; |
| import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument; |
| import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; |
| import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; |
| import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQueryAssociationProvider; |
| import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.ModelQueryImpl; |
| import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; |
| import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| |
| /** |
| * ModelQuery for JSP Tag files. Prioritizes the Tag content model and any |
| * loaded tag libraries in the model before falling back to the embedded model |
| * query, if one is found. |
| */ |
| public class TagModelQuery extends ModelQueryImpl implements ModelQuery { |
| /** |
| * The default mime-type for the embedded ModelQuery |
| */ |
| public static final String DEFAULT_MIMETYPE = "text/html"; |
| |
| |
| /** |
| * The prefix used with ProjectScope to find the (possibly user-set) |
| * embedded mime-type on a .tag file. |
| */ |
| private static final String PREFERENCE_PREFIX = "embeddedMimeType/"; |
| |
| public static String createPreferenceKey(IPath fullPath) { |
| return PREFERENCE_PREFIX + fullPath.removeFirstSegments(1).toString(); |
| } |
| |
| private ModelQuery fEmbeddedModelQuery; |
| |
| /** |
| * @param modelQueryAssociationProvider |
| */ |
| public TagModelQuery(ModelQueryAssociationProvider modelQueryAssociationProvider) { |
| super(modelQueryAssociationProvider); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @seeorg.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl. |
| * ModelQueryImpl#getCMElementDeclaration(org.w3c.dom.Element) |
| */ |
| public CMElementDeclaration getCMElementDeclaration(Element element) { |
| CMElementDeclaration cmElementDeclaration = super.getCMElementDeclaration(element); |
| if (cmElementDeclaration == null) { |
| ModelQuery embeddedModelQuery = getEmbeddedModelQuery(element); |
| if (embeddedModelQuery != null) { |
| return embeddedModelQuery.getCMElementDeclaration(element); |
| } |
| } |
| return cmElementDeclaration; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl. |
| * ModelQueryImpl#getCorrespondingCMDocument(org.w3c.dom.Node) |
| */ |
| public CMDocument getCorrespondingCMDocument(Node node) { |
| CMDocument document = super.getCorrespondingCMDocument(node); |
| if (document == null) { |
| ModelQuery embeddedModelQuery = getEmbeddedModelQuery(node); |
| if (embeddedModelQuery != null) { |
| return embeddedModelQuery.getCorrespondingCMDocument(node); |
| } |
| } |
| return document; |
| } |
| |
| private String getEmbeddedMimeType(Node node) { |
| String type = DEFAULT_MIMETYPE; |
| if (node instanceof IDOMNode) { |
| IStructuredModel model = ((IDOMNode) node).getModel(); |
| String baseLocation = model.getBaseLocation(); |
| if (!baseLocation.equals(IModelManager.UNMANAGED_MODEL)) { |
| IPath path = new Path(baseLocation); |
| if (path.segmentCount() > 1) { |
| String key = createPreferenceKey(path); |
| IEclipsePreferences preferences = new ProjectScope(ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0))).getNode(JSPCorePlugin.getDefault().getBundle().getSymbolicName()); |
| type = preferences.get(key, DEFAULT_MIMETYPE); |
| } |
| } |
| } |
| return type; |
| } |
| |
| private ModelQuery getEmbeddedModelQuery(Node node) { |
| if (fEmbeddedModelQuery == null) { |
| String embeddedMimeType = getEmbeddedMimeType(node); |
| if (embeddedMimeType != null) { |
| EmbeddedTypeHandler embeddedContentTypeHandler = ModelHandlerUtility.getEmbeddedContentTypeFor(embeddedMimeType); |
| if (embeddedContentTypeHandler != null) { |
| List adapterFactories = embeddedContentTypeHandler.getAdapterFactories(); |
| for (int i = 0; i < adapterFactories.size(); i++) { |
| INodeAdapterFactory factory = (INodeAdapterFactory) adapterFactories.get(i); |
| if (factory.isFactoryForType(ModelQueryAdapter.class)) { |
| INodeAdapter adapter = factory.adapt((INodeNotifier) node.getOwnerDocument()); |
| if (adapter instanceof ModelQueryAdapter) { |
| fEmbeddedModelQuery = ((ModelQueryAdapter) adapter).getModelQuery(); |
| } |
| } |
| } |
| } |
| } |
| } |
| return fEmbeddedModelQuery; |
| } |
| } |