blob: 73ef1cc04d91435e904095657f58863aeee138bb [file] [log] [blame]
/*******************************************************************************
* 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;
}
}