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

Source Code of org.eclipse.jst.jsp.core.internal.encoding.JSPDocumentLoader

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

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jst.jsp.core.internal.Assert;
import org.eclipse.jst.jsp.core.internal.JSPCoreMessages;
import org.eclipse.jst.jsp.core.internal.document.PageDirectiveWatcherFactory;
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.JSP11Namespace;
import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
import org.eclipse.jst.jsp.core.internal.text.StructuredTextPartitionerForJSP;
import org.eclipse.wst.sse.core.internal.PropagatingAdapter;
import org.eclipse.wst.sse.core.internal.document.AbstractDocumentLoader;
import org.eclipse.wst.sse.core.internal.document.IDocumentCharsetDetector;
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.encoding.CodedIO;
import org.eclipse.wst.sse.core.internal.encoding.CodedReaderCreator;
import org.eclipse.wst.sse.core.internal.encoding.ContentTypeEncodingPreferences;
import org.eclipse.wst.sse.core.internal.encoding.util.BufferedLimitedReader;
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.ltk.parser.TagMarker;
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.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.document.IEncodedDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.text.BasicStructuredDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
import org.w3c.dom.Document;

public class JSPDocumentLoader extends AbstractDocumentLoader {
  private final static String DEFAULT_MIME_TYPE = "text/html"; //$NON-NLS-1$
  private final static String SPEC_DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$

  protected static IFile getFileFor(IStructuredModel model) {
    if (model == null)
      return null;
    String path = model.getBaseLocation();
    if (path == null || path.length() == 0) {
      Object id = model.getId();
      if (id == null)
        return null;
      path = id.toString();
    }
    // TODO needs rework for linked resources
    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    IFile file = root.getFileForLocation(new Path(path));
    return file;
  }

  private EmbeddedTypeRegistry fEmbeddedContentTypeRegistry;

  public JSPDocumentLoader() {
    super();
  }

  protected void addNestablePrefix(JSPSourceParser parser, String tagName) {
    TagMarker bm = new TagMarker(tagName);
    parser.addNestablePrefix(bm);
  }

  synchronized public IEncodedDocument createNewStructuredDocument(IFile iFile) throws IOException, CoreException {
    IStructuredDocument structuredDocument = null;
    try {
      structuredDocument = createCodedDocument(iFile);

      EmbeddedTypeHandler embeddedType = getEmbeddedType(iFile);
      if (embeddedType != null)
        embeddedType.initializeParser(structuredDocument.getParser());

      fFullPreparedReader.reset();
      setDocumentContentsFromReader(structuredDocument, fFullPreparedReader);

    }
    finally {
      if (fFullPreparedReader != null) {
        fFullPreparedReader.close();
      }
    }
    return structuredDocument;
  }

  private IStructuredDocument createCodedDocument(IFile iFile) throws CoreException, UnsupportedEncodingException, IOException {
    IStructuredDocument structuredDocument = (IStructuredDocument) createNewStructuredDocument();

    getCodedReaderCreator().set(iFile);

    fFullPreparedReader = getCodedReaderCreator().getCodedReader();
    fEncodingMemento = getCodedReaderCreator().getEncodingMemento();

    structuredDocument.setEncodingMemento(getCodedReaderCreator().getEncodingMemento());

    return structuredDocument;
  }

  public IEncodedDocument createNewStructuredDocument(String filename, InputStream inputStream) throws UnsupportedEncodingException, IOException {
    if (filename == null && inputStream == null) {
      throw new IllegalArgumentException("can not have both null filename and inputstream"); //$NON-NLS-1$
    }
    IEncodedDocument structuredDocument = createNewStructuredDocument();
    CodedReaderCreator codedReaderCreator = new CodedReaderCreator();
    try {
      codedReaderCreator.set(filename, inputStream);
      fFullPreparedReader = codedReaderCreator.getCodedReader();
      fEncodingMemento = codedReaderCreator.getEncodingMemento();
      structuredDocument.setEncodingMemento(fEncodingMemento);
      // the fact that file is null means this method/code path is no
      // good for JSP fragments
      EmbeddedTypeHandler embeddedType = getEmbeddedType((IFile) null);
      fFullPreparedReader.reset();
      if (embeddedType != null)
        embeddedType.initializeParser(((IStructuredDocument) structuredDocument).getParser());
      setDocumentContentsFromReader(structuredDocument, fFullPreparedReader);
    }
    catch (CoreException e) {
      // impossible in this context
      throw new Error(e);
    }
    finally {
      if (fFullPreparedReader != null) {
        fFullPreparedReader.close();
      }
    }
    return structuredDocument;

  }

  /**
   * Method getDefaultDocumentPartitioner.
   *
   * @return IDocumentPartitioner
   */
  public IDocumentPartitioner getDefaultDocumentPartitioner() {
    return new StructuredTextPartitionerForJSP();
  }

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


  public IDocumentCharsetDetector getDocumentEncodingDetector() {
    if (fDocumentEncodingDetector == null) {
      fDocumentEncodingDetector = new JSPDocumentHeadContentDetector();
    }
    return fDocumentEncodingDetector;
  }

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

  /**
   * Determine the MIME content type specified in a page directive. This
   * should appear "as early as possible in the JSP page" according to the
   * JSP v1.2 specification.
   */
  private EmbeddedTypeHandler getEmbeddedType(IFile file) throws UnsupportedEncodingException, CoreException, IOException {
    EmbeddedTypeHandler handler = null;
    if (fFullPreparedReader == null) {
      handler = getJSPDefaultEmbeddedType();
    }
    else {
      String mimeType = null;

      IDocumentCharsetDetector jspProvider = getDocumentEncodingDetector();
      Reader fullPreparedReader = getFullPreparedReader();
      BufferedLimitedReader limitedReader = new BufferedLimitedReader(fullPreparedReader, CodedIO.MAX_BUF_SIZE);
      jspProvider.set(limitedReader);
      if (jspProvider instanceof IJSPHeadContentDetector) {
        mimeType = ((IJSPHeadContentDetector) jspProvider).getContentType();
        fullPreparedReader.reset();
      }

      EmbeddedTypeRegistry reg = getEmbeddedContentTypeRegistry();
      if (mimeType == null || mimeType.length() == 0) {
        handler = getJSPDefaultEmbeddedType();
      }
      else {
        handler = reg.getTypeFor(mimeType);
      }
    }
    return handler;
  }

  /**
   * 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() {
    EmbeddedTypeRegistry reg = getEmbeddedContentTypeRegistry();
    return reg.getTypeFor(getDefaultMimeType());
  }

  public RegionParser getParser() {
    // remember, the Loader
    // will need to finish initialization of parser
    // based on "embedded content"
    JSPSourceParser parser = new JSPSourceParser();
    // add default nestable tag list
    addNestablePrefix(parser, JSP11Namespace.JSP_TAG_PREFIX);
    return parser;
  }

  protected String getPreferredNewLineDelimiter(IFile file) {
    String delimiter = ContentTypeEncodingPreferences.getPreferredNewLineDelimiter(ContentTypeIdForJSP.ContentTypeID_JSP);
    if (delimiter == null)
      delimiter = super.getPreferredNewLineDelimiter(file);
    return delimiter;
  }

  /**
   * Specification cites ISO-8859-1/Latin-1 as the default charset.
   */
  protected String getSpecDefaultEncoding() {
    return SPEC_DEFAULT_ENCODING;
  }

  /**
   * 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.
   */
  protected IEncodedDocument newEncodedDocument() {
    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();
    embeddedType.initializeParser(structuredDocument.getParser());
    return structuredDocument;
  }

  public IDocumentLoader newInstance() {
    return new JSPDocumentLoader();
  }

  protected void preLoadAdapt(IStructuredModel structuredModel) {
    IDOMModel domModel = (IDOMModel) structuredModel;
    //
    // document must have already been set for this to
    // work.
    Document document = domModel.getDocument();
    Assert.isNotNull(document, JSPCoreMessages.JSPDocumentLoader_1);
    // 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());
    // 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);

  }

}
TOP

Related Classes of org.eclipse.jst.jsp.core.internal.encoding.JSPDocumentLoader

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.