Package org.eclipse.jst.jsp.core.internal.modelhandler

Source Code of org.eclipse.jst.jsp.core.internal.modelhandler.JSPModelLoader

/*******************************************************************************
* Copyright (c) 2004, 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.modelhandler;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.contentproperties.JSPFContentProperties;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveAdapter;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveAdapterFactory;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveWatcherFactory;
import org.eclipse.jst.jsp.core.internal.domdocument.DOMModelForJSP;
import org.eclipse.jst.jsp.core.internal.encoding.IJSPHeadContentDetector;
import org.eclipse.jst.jsp.core.internal.encoding.JSPDocumentHeadContentDetector;
import org.eclipse.jst.jsp.core.internal.encoding.JSPDocumentLoader;
import org.eclipse.jst.jsp.core.internal.modelquery.JSPModelQueryAdapterImpl;
import org.eclipse.jst.jsp.core.internal.modelquery.ModelQueryAdapterFactoryForJSP;
import org.eclipse.jst.jsp.core.internal.parser.JSPReParser;
import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.IContentDescriptionForJSP;
import org.eclipse.jst.jsp.core.internal.text.StructuredTextPartitionerForJSP;
import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeFamilyForHTML;
import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeIdForHTML;
import org.eclipse.wst.html.core.internal.text.StructuredTextPartitionerForHTML;
import org.eclipse.wst.sse.core.internal.PropagatingAdapter;
import org.eclipse.wst.sse.core.internal.document.DocumentReader;
import org.eclipse.wst.sse.core.internal.document.IDocumentLoader;
import org.eclipse.wst.sse.core.internal.document.StructuredDocumentFactory;
import org.eclipse.wst.sse.core.internal.ltk.modelhandler.EmbeddedTypeHandler;
import org.eclipse.wst.sse.core.internal.ltk.parser.RegionParser;
import org.eclipse.wst.sse.core.internal.model.AbstractModelLoader;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistry;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistryImpl;
import org.eclipse.wst.sse.core.internal.provisional.IModelLoader;
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.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.text.BasicStructuredDocument;
import org.eclipse.wst.sse.core.internal.util.Assert;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.xml.core.internal.DebugAdapterFactory;
import org.eclipse.wst.xml.core.internal.document.DOMModelImpl;
import org.eclipse.wst.xml.core.internal.propagate.PropagatingAdapterFactoryImpl;
import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
import org.eclipse.wst.xml.core.internal.text.rules.StructuredTextPartitionerForXML;
import org.w3c.dom.Document;

public class JSPModelLoader extends AbstractModelLoader {
  protected final int MAX_BUFFERED_SIZE_FOR_RESET_MARK = 200000;

  /**
   * DMW - Note: I think the embeddedTypeRegistry in IModelManager can be
   * removed
   */
  private EmbeddedTypeRegistry embeddedContentTypeRegistry;
  private final static String DEFAULT_MIME_TYPE = "text/html"; //$NON-NLS-1$
  private final static String DEFAULT_LANGUAGE = "java"; //$NON-NLS-1$

  public JSPModelLoader() {
    super();
  }

  /**
   * Gets the embeddedContentTypeRegistry.
   *
   * @return Returns a EmbeddedContentTypeRegistry
   */
  private EmbeddedTypeRegistry getEmbeddedContentTypeRegistry() {
    if (embeddedContentTypeRegistry == null) {
      embeddedContentTypeRegistry = EmbeddedTypeRegistryImpl.getInstance();
    }
    return embeddedContentTypeRegistry;
  }

  public IStructuredModel newModel() {
    DOMModelForJSP model = new DOMModelForJSP();
    return model;
  }

  /**
   * For JSP files, text/html is the default content type. This may want
   * this different for types like jsv (jsp for voice xml) For now, hard
   * code to new instance. In future, should get instance from registry.
   *
   * Specification cites HTML as the default contentType.
   */
  private EmbeddedTypeHandler getJSPDefaultEmbeddedType(IStructuredModel model) {
    EmbeddedTypeRegistry reg = getEmbeddedContentTypeRegistry();

    String mimeType = null;
    // default embedded type for fragments
    if (model != null) {
      IFile file = getFile(model);
      if (file != null) {
        mimeType = JSPFContentProperties.getProperty(JSPFContentProperties.JSPCONTENTTYPE, file, true);
      }
    }
    mimeType = mimeType == null ? getDefaultMimeType() : mimeType;
    return reg.getTypeFor(mimeType);
  }

  /**
   * Method getDefaultMimeType.
   *
   * @return String
   */
  private String getDefaultMimeType() {
    return DEFAULT_MIME_TYPE;
  }

  /**
   * This method must return a new instance of IStructuredDocument, that has
   * been initialized with appropriate parser. For many loaders, the
   * (default) parser used is known for any input. For others, the correct
   * parser (and its initialization) is normall dependent on the content of
   * the file. This no-argument method should assume "empty input" and would
   * therefore return the default parser for the default contentType.
   *
   * If the parser is to handle tag libraries, it must have a TaglibSupport
   * object with a valid URIResolver and this IStructuredDocument attached
   * to it before the contents are set on the IStructuredDocument.
   */
  public IStructuredDocument newStructuredDocument() {
    IStructuredDocument structuredDocument = StructuredDocumentFactory.getNewStructuredDocumentInstance(getParser());
    ((BasicStructuredDocument) structuredDocument).setReParser(new JSPReParser());
    // structuredDocument.setDocumentPartitioner(new
    // JSPJavaDocumentPartioner());
    // even though this is an "empty model" ... we want it to have at
    // least the
    // default embeddeded content type handler
    EmbeddedTypeHandler embeddedType = getJSPDefaultEmbeddedType(null);
    embeddedType.initializeParser(structuredDocument.getParser());
    return structuredDocument;
  }

  public RegionParser getParser() {
    // remember, the Loader
    // will need to finish initialization of parser
    // based on "embedded content"
    return new JSPSourceParser();
  }

  protected void preLoadAdapt(IStructuredModel structuredModel) {
    super.preLoadAdapt(structuredModel);
    IDOMModel domModel = (IDOMModel) structuredModel;
    //
    // document must have already been set for this to
    // work.
    Document document = domModel.getDocument();
    Assert.isNotNull(document);
    // if there is a model in the adapter, this will adapt it to
    // first node. After that the PropagatingAdater spreads over the
    // children being
    // created. Each time that happends, a side effect is to
    // also "spread" sprecific registered adapters,
    // they two can propigate is needed.
    // This 'get' causes first to be be attached.
    PropagatingAdapter propagatingAdapter = (PropagatingAdapter) ((INodeNotifier) document).getAdapterFor(PropagatingAdapter.class);
    // may make this easier to use in futue
    propagatingAdapter.addAdaptOnCreateFactory(new PageDirectiveWatcherFactory());
    if (Debug.debugNotificationAndEvents) {
      propagatingAdapter.addAdaptOnCreateFactory(new DebugAdapterFactory());
    }
    // For JSPs, the ModelQueryAdapter must be "attached" to the document
    // before content is set in the model, so taglib initization can
    // take place.
    ((INodeNotifier) document).getAdapterFor(ModelQueryAdapter.class);
    //

  }

  /**
   * This method must return those factories which must be attached to the
   * structuredModel before content is applied.
   */
  public List getAdapterFactories() {
    List result = new ArrayList();
    INodeAdapterFactory factory = null;
    //
    factory = new ModelQueryAdapterFactoryForJSP();
    result.add(factory);
    factory = new PropagatingAdapterFactoryImpl();
    result.add(factory);
    factory = new PageDirectiveAdapterFactory();
    result.add(factory);

    return result;
  }


  public IJSPHeadContentDetector getHeadParser() {
    return new JSPDocumentHeadContentDetector();
  }

  private IContentDescription getContentDescription(IDocument doc) {
    if (doc == null)
      return null;
    DocumentReader reader = new DocumentReader(doc);
    return getContentDescription(reader);
  }

  /**
   * Returns content description for an input stream Assumes it's JSP
   * content. Closes the input stream when finished.
   *
   * @param reader
   * @return the IContentDescription for in, or null if in is null
   */
  private IContentDescription getContentDescription(Reader reader) {

    if (reader == null)
      return null;

    IContentDescription desc = null;
    try {

      IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
      desc = contentTypeJSP.getDescriptionFor(reader, IContentDescription.ALL);
    }
    catch (IOException e) {
      Logger.logException(e);
    }
    finally {
      if (reader != null) {
        try {
          reader.close();
        }
        catch (IOException e) {
          Logger.logException(e);
        }
      }
    }
    return desc;
  }

  private IFile getFile(IStructuredModel model) {
    if (model != null) {
      String location = model.getBaseLocation();
      if (location != null) {
        IPath path = new Path(location);
        if (!path.toFile().exists() && path.segmentCount() > 1) {
          return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
        }
      }
    }
    return null;
  }

  /**
   * Method getLanguage.
   *
   * @param model
   * @return String
   */
  private String getLanguage(IStructuredModel model) {
    String result = null;
    // first check the model (document itself) to see if contains
    result = getLanguageFromStructuredDocument(model.getStructuredDocument());
    // Note: if model contains an unsupported
    // language, we'll even return it,
    // since who knows what future holds.

    // get default language specified in properties page
    IFile file = getFile(model);
    result = JSPFContentProperties.getProperty(JSPFContentProperties.JSPLANGUAGE, file, true);

    // always return something
    if (result == null) {
      result = DEFAULT_LANGUAGE;
    }
    return result;
  }

  /**
   * Method getLanguageFromStructuredDocument.
   *
   * @param structuredDocument
   * @return String
   */
  private String getLanguageFromStructuredDocument(IStructuredDocument structuredDocument) {
    if (structuredDocument == null)
      return null;
    String result = null;
    // bascially same algorithm as get encoding or
    // get content type from structuredDocument.
    IJSPHeadContentDetector localHeadParser = getHeadParser();
    // we can be assured that its already been
    // parsed. If not call parseHeaderForPageDirective()
    // before calling getLanguage;
    localHeadParser.set(structuredDocument);
    try {
      result = localHeadParser.getLanguage();
    }
    catch (IOException e) {
      // impossible
      // TODO need to reconsider design to avoid
      throw new Error(e);
    }
    return result;
  }

  /**
   * This is "reinitialize" since there should always be at least the
   * default one assigned, before we start checking the stream
   */
  private void reInitializeEmbeddedType(IStructuredModel model, EmbeddedTypeHandler oldEmbeddedContentType, EmbeddedTypeHandler newEmbeddedContentType) {
    // check program logic
    Assert.isNotNull(oldEmbeddedContentType, "Program error: invalid call during model initialization"); //$NON-NLS-1$
    // once we know the embedded content type, we need to set it in the
    // PageDirectiveAdapter ... the order of initialization is
    // critical here, the doc must have been created, but its contents not
    // set yet,
    // and all factories must have been set up also.
    IDOMModel domModel = (IDOMModel) model;
    IStructuredDocument structuredDocument = model.getStructuredDocument();
    IDOMDocument document = domModel.getDocument();
    PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getExistingAdapter(PageDirectiveAdapter.class);
    // ==> // PropagatingAdapter propagatingAdapter = (PropagatingAdapter)
    // ((INodeNotifier)
    // document).getExistingAdapter(PropagatingAdapter.class);
    // ==> // ModelQueryAdapter modelQueryAdapter = (ModelQueryAdapter)
    // ((INodeNotifier)
    // document).getExistingAdapter(ModelQueryAdapter.class);
    oldEmbeddedContentType.uninitializeFactoryRegistry(model.getFactoryRegistry());
    oldEmbeddedContentType.uninitializeParser(structuredDocument.getParser());
    // since 'document' is not recreated in this
    // reinit path, we need to remove all adapters,
    // except for the propagated adapters (including page
    // directive adapter, and model query adapter).
    // to accomplish this, we'll just remove all, then
    // add back with a call to pre-load adapt.
    // let clients decide to unload adapters from document
    // Collection oldAdapters = document.getAdapters();
    // Iterator oldAdaptersIterator = oldAdapters.iterator();
    // while (oldAdaptersIterator.hasNext()) {
    // INodeAdapter oldAdapter = (INodeAdapter)
    // oldAdaptersIterator.next();
    // if (oldAdapter != pageDirectiveAdapter && oldAdapter !=
    // propagatingAdapter && oldAdapter != modelQueryAdapter) {
    // // DO NOT remove directly!
    // // can change contents while in notifity loop!
    // //oldAdaptersIterator.remove();
    // document.removeAdapter(oldAdapter);
    // }
    // }
    // DMW: I believe something like the following is needed,
    // since releases cached adapters
    // if (document instanceof DocumentImpl) {
    // ((DocumentImpl) document).releaseDocumentType();
    // ((DocumentImpl) document).releaseStyleSheets();
    // }
    // remember, embedded type factories are automatically cleared when
    // embededType changed
    pageDirectiveAdapter.setEmbeddedType(newEmbeddedContentType);
    // // but still need to clear the page directive watchers, and let
    // them be rediscovered (with new, accurate node as target)
    // pageDirectiveAdapter.clearPageWatchers();
    if (newEmbeddedContentType != null) {

      // need to null out or else ModelParserAdapter
      // won't get reinitialized
      ((DOMModelImpl) model).setModelParser(null);

      newEmbeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
      newEmbeddedContentType.initializeParser(structuredDocument.getParser());

      // partitioner setup is the responsibility of this loader
      IDocumentPartitioner documentPartitioner = structuredDocument.getDocumentPartitioner();
      // ISSUE: this logic is flawed, not sure of original intent, but
      // added null/type checks for safety.
      if (documentPartitioner != null && documentPartitioner instanceof StructuredTextPartitionerForJSP) {
        if (newEmbeddedContentType.getFamilyId().equals(ContentTypeIdForXML.ContentTypeID_XML)) {
          ((StructuredTextPartitionerForJSP) documentPartitioner).setEmbeddedPartitioner(new StructuredTextPartitionerForXML());
        }
        else if (newEmbeddedContentType.getFamilyId().equals(ContentTypeIdForHTML.ContentTypeID_HTML)) {
          ((StructuredTextPartitionerForJSP) documentPartitioner).setEmbeddedPartitioner(new StructuredTextPartitionerForHTML());
        }
      }
    }
    // adding language here, in this convienent central
    // location, but some obvious renaming or refactoring
    // wouldn't hurt, in future.
    // I needed to add this language setting for JSP Fragment support
    // Note: this is the one that counts, since at this point,
    // the model has an ID, so we can look up IFile, etc.
    String language = getLanguage(model);
    if (language != null && language.length() > 0) {
      pageDirectiveAdapter.setLanguage(language);
    }
  }

  /**
   * This is "reinitialize" since there should always be at least the
   * default one assigned, before we start checking the stream
   */
  private void initCloneOfEmbeddedType(IStructuredModel model, EmbeddedTypeHandler oldEmbeddedContentType, EmbeddedTypeHandler newEmbeddedContentType) {
    // check program logic
    Assert.isNotNull(oldEmbeddedContentType, "Program error: invalid call during model initialization"); //$NON-NLS-1$
    // once we know the embedded content type, we need to set it in the
    // PageDirectiveAdapter ... the order of initialization is
    // critical here, the doc must have been created, but its contents not
    // set yet,
    // and all factories must have been set up also.
    IDOMModel domModel = (IDOMModel) model;
    IStructuredDocument structuredDocument = model.getStructuredDocument();
    IDOMDocument document = domModel.getDocument();
    PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getAdapterFor(PageDirectiveAdapter.class);
    // ==> // PropagatingAdapter propagatingAdapter = (PropagatingAdapter)
    // ((INodeNotifier) document).getAdapterFor(PropagatingAdapter.class);
    // ==> // ModelQueryAdapter modelQueryAdapter = (ModelQueryAdapter)
    // ((INodeNotifier) document).getAdapterFor(ModelQueryAdapter.class);
    // because, even in the clone case, the model has been paritally
    // intialized with
    // the old embedded type (during createModel), we need to unitialize
    // parts of it, based on the old (or default) ones
    oldEmbeddedContentType.uninitializeFactoryRegistry(model.getFactoryRegistry());
    oldEmbeddedContentType.uninitializeParser(structuredDocument.getParser());
    // remember, embedded type factories are automatically cleared when
    // embededType changed
    pageDirectiveAdapter.setEmbeddedType(newEmbeddedContentType);
    if (newEmbeddedContentType != null) {
      newEmbeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
      newEmbeddedContentType.initializeParser(structuredDocument.getParser());
    }
    // adding language here, in this convienent central
    // location, but some obvious renaming or refactoring
    // wouldn't hurt, in future.
    // I needed to add this language setting for JSP Fragment support
    // Note: this is the one that counts, since at this point,
    // the model has an ID, so we can look up IFile, etc.
    String language = getLanguage(model);
    if (language != null && language.length() > 0) {
      pageDirectiveAdapter.setLanguage(language);
    }
  }

  private EmbeddedTypeHandler getEmbeddedType(IStructuredModel model) {
    Document doc = ((IDOMModel) model).getDocument();
    PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) ((INodeNotifier) doc).getAdapterFor(PageDirectiveAdapter.class);
    EmbeddedTypeHandler embeddedHandler = pageDirectiveAdapter.getEmbeddedType();
    return embeddedHandler;
  }
 
  /* (non-Javadoc)
   * @see org.eclipse.wst.sse.core.internal.model.AbstractModelLoader#initEmbeddedTypePre(org.eclipse.wst.sse.core.internal.provisional.IStructuredModel)
   */
  protected void initEmbeddedTypePre(IStructuredModel model) {
    JSPModelLoader.this.initEmbeddedTypePre(model, model.getStructuredDocument());
  }

  protected void initEmbeddedTypePre(IStructuredModel model, IStructuredDocument structuredDocument) {

    // note: this will currently only work for models backed by files
    EmbeddedTypeHandler embeddedContentType = null;
    IDOMModel domModel = (IDOMModel) model;

    if (embeddedContentType == null) {
      IContentDescription desc = getContentDescription(structuredDocument);
      if (desc != null) {
        Object prop = null;

        prop = desc.getProperty(IContentDescriptionForJSP.CONTENT_FAMILY_ATTRIBUTE);
        if (prop != null) {
          if (ContentTypeFamilyForHTML.HTML_FAMILY.equals(prop)) {
            embeddedContentType = EmbeddedTypeRegistryImpl.getInstance().getTypeFor("text/html");
          }
        }

        if (embeddedContentType == null) {

          prop = desc.getProperty(IContentDescriptionForJSP.CONTENT_TYPE_ATTRIBUTE);
          if (prop != null) {
            embeddedContentType = EmbeddedTypeRegistryImpl.getInstance().getTypeFor((String) prop);
          }
        }
      }
    }

    IDOMDocument document = domModel.getDocument();
    PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getAdapterFor(PageDirectiveAdapter.class);

    if (embeddedContentType != null) {
      pageDirectiveAdapter.setEmbeddedType(embeddedContentType);
      embeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
    }
    else {
      // use default embeddedType if it couldn't determine one
      embeddedContentType = getJSPDefaultEmbeddedType(model);
      pageDirectiveAdapter.setEmbeddedType(embeddedContentType);
      embeddedContentType.initializeFactoryRegistry(model.getFactoryRegistry());
    }
  }

  protected void initEmbeddedTypePost(IStructuredModel model) {
    // should already be initialized (from initEmbeddedTypePre)
    // via IContentDescription
    setLanguageInPageDirective(model);
  }

  /**
   * As part of the model cloning process, ensure that the new model has the
   * same embedded content type handler as the old model, and that it is
   * properly initialized
   */
  protected void initEmbeddedType(IStructuredModel oldModel, IStructuredModel newModel) {
    EmbeddedTypeHandler existingEmbeddedType = getEmbeddedType(oldModel);
    if (existingEmbeddedType == null) {
      initEmbeddedTypePre(newModel, newModel.getStructuredDocument());
      initEmbeddedTypePost(newModel);
    }
    else {
      EmbeddedTypeHandler newEmbeddedContentType = existingEmbeddedType.newInstance();
      // initEmbeddedType(newModel);
      initCloneOfEmbeddedType(newModel, existingEmbeddedType, newEmbeddedContentType);
      setLanguageInPageDirective(newModel);
    }
  }

  protected void setLanguageInPageDirective(IStructuredModel newModel) {
    if (newModel instanceof IDOMModel) {
      IDOMDocument document = ((IDOMModel) newModel).getDocument();
      PageDirectiveAdapter pageDirectiveAdapter = (PageDirectiveAdapter) document.getAdapterFor(PageDirectiveAdapter.class);
      String language = getLanguage(newModel);
      pageDirectiveAdapter.setLanguage(language);
    }
  }

  public IStructuredModel reinitialize(IStructuredModel model) {
    EmbeddedTypeHandler oldHandler = null;
    EmbeddedTypeHandler newHandler = null;
    Object reinitStateData = model.getReinitializeStateData();
    if (reinitStateData instanceof EmbeddedTypeStateData) {
      EmbeddedTypeStateData oldStateData = (EmbeddedTypeStateData) reinitStateData;
      oldHandler = oldStateData.getOldHandler();
      newHandler = oldStateData.getNewHandler();
      // note. We should already have the new handler in the model's
      // (documents) adapters,
      // so need need to use the old one to undo the old state data
      reInitializeEmbeddedType(model, oldHandler, newHandler);
    }
    else {
      // for language ... we someday MIGHT have to do something
      // here, but for now, we don't have any model-side language
      // sensitive adapters.
    }
    return super.reinitialize(model);
  }

  public IModelLoader newInstance() {
    return new JSPModelLoader();
  }

  public IDocumentLoader getDocumentLoader() {
    if (documentLoaderInstance == null) {
      documentLoaderInstance = new JSPDocumentLoader();
    }
    return documentLoaderInstance;
  }

  /**
   * Ensures that an InputStream has mark/reset support.
   */
  public static InputStream getMarkSupportedStream(InputStream original) {
    if (original == null)
      return null;
    if (original.markSupported())
      return original;
    return new BufferedInputStream(original);
  }

  protected byte[] getBytes(InputStream inputStream, int max) throws IOException {
    byte[] smallBuffer = new byte[max];
    byte[] returnBuffer = null;
    int nRead = inputStream.read(smallBuffer, 0, max);
    if (nRead < max) {
      // empty file will return -1;
      if (nRead < 0)
        nRead = 0;
      byte[] smallerBuffer = new byte[nRead];
      System.arraycopy(smallBuffer, 0, smallerBuffer, 0, nRead);
      returnBuffer = smallerBuffer;
    }
    else {
      returnBuffer = smallBuffer;
    }
    return returnBuffer;
  }

  public IStructuredModel createModel(IStructuredModel oldModel) {
    IStructuredModel model = super.createModel(oldModel);
    // For JSPs, the ModelQueryAdapter must be "attached" to the document
    // before content is set in the model, so taglib initialization can
    // take place.
    // In this "clone model" case, we create a ModelQuery adapter
    // create a new instance from the old data. Note: I think this
    // "forced fit" only works here since the implementation of
    // ModelQueryAdapter does not
    // have to be released.

    ModelQueryAdapter modelQueryAdapter = getModelQueryAdapter(model);
    if (modelQueryAdapter == null) {
      modelQueryAdapter = getModelQueryAdapter(oldModel);
      IDOMDocument document = ((IDOMModel) model).getDocument();
      document.addAdapter(new JSPModelQueryAdapterImpl(modelQueryAdapter.getCMDocumentCache(), modelQueryAdapter.getModelQuery(), modelQueryAdapter.getIdResolver()));

    }



    return model;
  }

  private ModelQueryAdapter getModelQueryAdapter(IStructuredModel model) {
    IDOMDocument document = ((IDOMModel) model).getDocument();

    ModelQueryAdapter modelQueryAdapter = (ModelQueryAdapter) ((INodeNotifier) document).getAdapterFor(ModelQueryAdapter.class);
    return modelQueryAdapter;
  }

}
TOP

Related Classes of org.eclipse.jst.jsp.core.internal.modelhandler.JSPModelLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.