/******************************************************************************* * Copyright (c) 2004, 2007 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.wst.html.core.internal.modelquery; import java.io.File; import java.net.URI; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver; import org.eclipse.wst.html.core.internal.Logger; import org.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory; import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener; 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.sse.core.internal.util.Debug; import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache; import org.eclipse.wst.xml.core.internal.modelquery.XMLCatalogIdResolver; 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.ModelQueryAdapterImpl; /** * Creates a ModelQueryAdapter for HTML models */ public class ModelQueryAdapterFactoryForHTML extends AbstractAdapterFactory { ModelQueryAdapterImpl modelQueryAdapter; IStructuredModel modelStateNotifier; private InternalModelStateListener internalModelStateListener; class InternalModelStateListener implements IModelStateListener { /** * @see IModelStateListener#modelAboutToBeChanged(IStructuredModel) */ public void modelAboutToBeChanged(IStructuredModel model) { // ISSUE: should we "freeze" state, or anything? } public void modelAboutToBeReinitialized(IStructuredModel structuredModel) { // ISSUE: should we "freeze" state, or anything? } /** * @see IModelStateListener#modelChanged(IStructuredModel) */ public void modelChanged(IStructuredModel model) { // nothing to do? } /** * @see IModelStateListener#modelDirtyStateChanged(IStructuredModel, * boolean) */ public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) { // nothing to do } public void modelReinitialized(IStructuredModel structuredModel) { updateResolver(structuredModel); } /** * @see IModelStateListener#modelResourceDeleted(IStructuredModel) */ public void modelResourceDeleted(IStructuredModel model) { // nothing to do? } /** * @see IModelStateListener#modelResourceMoved(IStructuredModel, * IStructuredModel) */ public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) { modelStateNotifier.removeModelStateListener(this); modelStateNotifier = newModel; updateResolver(modelStateNotifier); modelStateNotifier.addModelStateListener(this); } private void updateResolver(IStructuredModel model) { String baseLocation = model.getBaseLocation(); IFile baseFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(model.getBaseLocation())); if (baseFile != null) { if (baseFile.getLocation() != null) { baseLocation = baseFile.getLocation().toString(); } if (baseLocation == null && baseFile.getLocationURI() != null) { baseLocation = baseFile.getLocationURI().toString(); } if (baseLocation == null) { baseLocation = baseFile.getFullPath().toString(); } } else { baseLocation = model.getBaseLocation(); } modelQueryAdapter.setIdResolver(new XMLCatalogIdResolver(baseLocation, model.getResolver())); } } /** * ModelQueryAdapterFactoryForHTML constructor comment. Note: this is a * case there the key is not exactly same as the class we are after. */ public ModelQueryAdapterFactoryForHTML() { super(ModelQueryAdapter.class, true); } /** * We need this protected version to allow subclasses to pass up standard * behaviour. * * @param adapterKey * @param registerAdapters */ protected ModelQueryAdapterFactoryForHTML(Object adapterKey, boolean registerAdapters) { super(adapterKey, registerAdapters); } public INodeAdapterFactory copy() { return new ModelQueryAdapterFactoryForHTML(); } public void release() { super.release(); if (modelStateNotifier != null) { modelStateNotifier.removeModelStateListener(internalModelStateListener); } modelStateNotifier = null; if (modelQueryAdapter != null) { modelQueryAdapter.release(); } } /** * createAdapter method comment. * * XXX: we must make this method more independent of 'location' (at least * provide some fall-back method). */ protected INodeAdapter createAdapter(INodeNotifier target) { if (Debug.displayInfo) { Logger.log(Logger.INFO_DEBUG, "-----------------------ModelQueryAdapterFactoryForHTML.createAdapter" + target); //$NON-NLS-1$ } if (modelQueryAdapter == null) { if (target instanceof IDOMNode) { IDOMNode xmlNode = (IDOMNode) target; modelStateNotifier = xmlNode.getModel(); modelStateNotifier.addModelStateListener(getInternalModelStateListener()); IStructuredModel model = xmlNode.getModel(); org.eclipse.wst.sse.core.internal.util.URIResolver resolver = model.getResolver(); if (Debug.displayInfo) System.out.println("----------------ModelQueryAdapterFactoryForHTML... baseLocation : " + resolver.getFileBaseLocation()); //$NON-NLS-1$ /** * XMLCatalogIdResolver currently requires a filesystem * location string. Customarily this will be what is in the * deprecated SSE URIResolver and required by the Common URI * Resolver. */ URIResolver idResolver = null; if (resolver != null) { idResolver = new XMLCatalogIdResolver(resolver.getFileBaseLocation(), resolver); } else { /* * 203649 - this block may be necessary due to ordering of * setting the resolver into the model */ String baseLocation = null; String modelsBaseLocation = model.getBaseLocation(); if (modelsBaseLocation != null) { File file = new Path(modelsBaseLocation).toFile(); if (file.exists()) { baseLocation = file.getAbsolutePath(); } else { IPath basePath = new Path(model.getBaseLocation()); IResource derivedResource = null; if (basePath.segmentCount() > 1) derivedResource = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath); else derivedResource = ResourcesPlugin.getWorkspace().getRoot().getProject(basePath.segment(0)); IPath derivedPath = derivedResource.getLocation(); if (derivedPath != null) { baseLocation = derivedPath.toString(); } else { URI uri = derivedResource.getLocationURI(); if (uri != null) { baseLocation = uri.toString(); } } } if(baseLocation == null) { baseLocation = modelsBaseLocation; } } idResolver = new XMLCatalogIdResolver(baseLocation, null); } CMDocumentCache documentCache = new CMDocumentCache(); ModelQuery modelQuery = new HTMLModelQueryImpl(documentCache, idResolver); modelQuery.setEditMode(ModelQuery.EDIT_MODE_UNCONSTRAINED); modelQueryAdapter = new ModelQueryAdapterImpl(documentCache, modelQuery, idResolver); } } return modelQueryAdapter; } private final InternalModelStateListener getInternalModelStateListener() { if (internalModelStateListener == null) { internalModelStateListener = new InternalModelStateListener(); } return internalModelStateListener; } }