/******************************************************************************* * 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.IProject; 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.common.uriresolver.internal.provisional.URIResolver; 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.eclipse.wst.xml.core.internal.ssemodelquery.MovableModelQuery; 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, MovableModelQuery { /** * 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) * * @see org.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) { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)); if (project.isAccessible()) { String key = createPreferenceKey(path); IEclipsePreferences preferences = new ProjectScope(project).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; } /* (non-Javadoc) * @see org.eclipse.wst.xml.core.internal.ssemodelquery.MovableModelQuery#setIdResolver(org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver) */ public void setIdResolver(URIResolver newURIResolver) { fEmbeddedModelQuery = null; } }