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

Source Code of org.eclipse.jst.jsp.core.internal.java.JSPTranslatorPersister

/*******************************************************************************
* Copyright (c) 2010 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.java;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.zip.CRC32;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jst.jsp.core.internal.JSPCorePlugin;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.java.search.JSPIndexManager;
import org.eclipse.jst.jsp.core.internal.modelhandler.ModelHandlerForJSP;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.FileBufferModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

/**
* <p>This is a static class used to persist JSP translations and retrieve the persisted
* translations.</p>
*
* <p>It is not actually in charge of finding files to persist, rather it provides API
* for some other mechanism that tracks JSP files to call into to persist the translations.</p>
*
* <p>This class can be deactivated through the <code>persistJSPTranslations</code> system property,
* a value of <code>true</code> means the persister is activated (which is the default), value of
* <code>false</code> means the persister is not activated.</p>
*
* @see JSPIndexManager
*/
public class JSPTranslatorPersister{
  /**
   * <code>true</code> if the persister is activated, <code>false</code>
   * otherwise.  This is determined by checking the system property
   * <code>persistJSPTranslations</code>, if no value supplied then
   * default is <code>true</code>
   */
  public static final boolean ACTIVATED =
    Boolean.valueOf(System.getProperty("persistJSPTranslations", "true")).booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$
 
  /** the location where {@link JSPTranslator}s are externalized too for persistence purposes */
  private static final IPath PERSIST_LOCATION = JSPCorePlugin.getDefault().getStateLocation().append("translators"); //$NON-NLS-1$
 
  /** used to calculate persisted translator file names */
  private static final CRC32 CHECKSUM_CALC = new CRC32();
 
  /** lock to use while using the checksum */
  private static final Object CHECKSUM_CALC_LOCK = new Object();
 
  /**
   * <p>Private constructor to prevent creating an instance of this class</p>
   */
  private JSPTranslatorPersister() {
  }
 
  /**
   * <p>Given the {@link IStructuredModel} of a JSP file attempts to retrieve the persisted
   * {@link JSPTranslator} for that model.</p>
   * <p><b>NOTE: </b><i>It is possible for there not to be a persisted translator</i></p>
   *
   * @param model {@link IStructuredModel} to get the persisted {@link JSPTranslator} for
   * @return the persisted {@link JSPTranslator} for the given <code>model</code>, or
   * <code>null</code> if none could be found or an existing one could not be read
   */
  public static JSPTranslator getPersistedTranslator(IStructuredModel model) {
    String persistedTranslatorFilePath = getPersistedTranslatorFilePath(model.getBaseLocation());
    File persistedTranslatorFile = new File(persistedTranslatorFilePath);
   
    //attempt to read in the externalized translator
    JSPTranslator translator = null;
    ObjectInputStream in = null;
    try {
      //get the persisted translator file if one exists
      if(persistedTranslatorFile.exists()) {
        long persistedTranslatorFileTimestamp = persistedTranslatorFile.lastModified();
        long jspFileTimestamp = FileBufferModelManager.getInstance().getBuffer(
            model.getStructuredDocument()).getModificationStamp();
       
        /* if the persisted translator timestamp is newer then the jsp file timestamp
         * then the translation has not become stale, otherwise it has so delete
         * it and don't use it */
        if(persistedTranslatorFileTimestamp > jspFileTimestamp) {
          FileInputStream fis = new FileInputStream(persistedTranslatorFile);
          in = new ObjectInputStream(fis);
          translator = (JSPTranslator)in.readObject();
         
          //do post read external setup
          if(translator != null) {
            translator.postReadExternalSetup(model);
          }
        } else {
          persistedTranslatorFile.delete();
        }
      }
    } catch(InvalidClassException e) {
      /* this means that the externalized translator is for an older version
       * of the JSPTranslator, so delete it */
      persistedTranslatorFile.delete();
    }catch (IOException e) {
      Logger.logException("Could not read externalized JSPTranslator at " + persistedTranslatorFilePath, e); //$NON-NLS-1$
    } catch (ClassNotFoundException e) {
      Logger.logException("Class of a serialized JSPTranslator cannot be found", e); //$NON-NLS-1$
    } finally {
      if(in != null) {
        try {
          in.close();
        } catch (IOException e) {
          Logger.logException("Could not close externalized JSPTranslator that was just read", e); //$NON-NLS-1$
        }
      }
    }
   
    return translator;
  }
 
  /**
   * @param resource JSP resource who's translation should be persisted
   */
  public static void persistTranslation(IResource resource) {
    if(ACTIVATED) {
      IPath path = resource.getFullPath();
      String filePath = getPersistedTranslatorFilePath(path.toString());
      IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
 
      JSPTranslator translator = getJSPTranslator(file);
      if(translator != null) {
        persistTranslator(translator, filePath);
      }
    }
  }
 
  /**
   * @param resource JSP resource who's translation should no longer be persisted
   */
  public static void removePersistedTranslation(IResource resource) {
    if(ACTIVATED) {
      File file = getPersistedFile(resource.getFullPath());
      file.delete();
    }
  }
 
  /**
   * @param resource JSP resource that has moved and thus its persisted translation should be updated
   * @param fromPath Path the JSP resource moved from
   */
  public static void movePersistedTranslation(IResource resource, IPath fromPath) {
    if(ACTIVATED) {
      File from = getPersistedFile(fromPath);
      File to = getPersistedFile(resource.getFullPath());
 
      from.renameTo(to);
    }
  }
 
  /**
   * <p>Given the path to a JSP file determines the path to its persisted {@link JSPTranslator}</p>
   *
   * @param jspFilePath {@link IPath} to JSP file for which the path to its persisted {@link JSPTranslator}
   * should be determined
   *
   * @return OS file path to the persisted {@link JSPTranslator} associated with the JSP file at
   * <code>jspFilePath</code>
   */
  private static String getPersistedTranslatorFilePath(String jspFilePath) {
    String persistedTranslatorFileName = "error.translator"; //$NON-NLS-1$
    synchronized(CHECKSUM_CALC_LOCK){
      try {
        CHECKSUM_CALC.reset();
        CHECKSUM_CALC.update(jspFilePath.getBytes("utf16")); //$NON-NLS-1$
        persistedTranslatorFileName = Long.toString(CHECKSUM_CALC.getValue()) + ".translator"; //$NON-NLS-1$
      } catch (UnsupportedEncodingException e) {
        Logger.logException("Could not get utf16 encoded bytes to create checksum to store persisted file.", e); //$NON-NLS-1$
      }
    }
   
    IPath location = PERSIST_LOCATION;
   
    // ensure the folder exists on disk
        File folder = new File(location.toOSString());
    if (!folder.isDirectory()) {
      try {
        folder.mkdir();
      }
      catch (SecurityException e) {
      }
    }
   
    location = location.addTrailingSeparator();
    location = location.append(persistedTranslatorFileName);
    return location.toOSString();
  }
 
  /**
   * <p>Gets the associated {@link JSPTranslator} for a specific JSP file.</p>
   * <p><b>NOTE: </b><i>This does not get the persisted translator but rather the
   * associated translator in memory</i></p>
   *
   * @param jspFile {@link IFile} to the JSP file that the associated {@link JSPTranslator}
   * is needed for
   * @return {@link JSPTranslator} associated with the given <code>jspFilePath</code>, or
   * <code>null</code> if none can be found.
   */
  private static JSPTranslator getJSPTranslator(IFile jspFile) {
    IStructuredModel model = null;
    JSPTranslator translator = null;
    try {
      model = StructuredModelManager.getModelManager().getModelForRead(jspFile);
      if(model instanceof IDOMModel) {
        IDOMDocument doc = ((IDOMModel)model).getDocument();
        ModelHandlerForJSP.ensureTranslationAdapterFactory(model);
        JSPTranslationAdapter adapter = (JSPTranslationAdapter)doc.getAdapterFor(IJSPTranslation.class);
       
        //don't want to persist a translator that has not already been requested
        if(adapter != null && adapter.hasTranslation()) {
          translator = adapter.getJSPTranslation().getTranslator();
        }
      }
    } catch (IOException e) {
      Logger.logException("Could not get translator for " + jspFile.getName() + //$NON-NLS-1$
          " because could not read model for same.", e); //$NON-NLS-1$
    } catch (CoreException e) {
      Logger.logException("Could not get translator for " + jspFile.getName() + //$NON-NLS-1$
          " because could not read model for same.", e); //$NON-NLS-1$
    } finally {
      if(model != null) {
        model.releaseFromRead();
      }
    }
   
    return translator;
  }
 
  /**
   * <p>Persists a {@link JSPTranslator} to disk for a specific JSP file</p>
   *
   * @param translator {@link JSPTranslator} to persist to disk
   * @param jspFilePath {@link IPath} to the JSP file the given <code>translator</code> is for
   */
  private static void persistTranslator(JSPTranslator translator, String filePath) {
    try {
      FileOutputStream fos = new FileOutputStream(filePath);
      ObjectOutputStream out = new ObjectOutputStream(fos);
      out.writeObject(translator);
      out.close();
    } catch (IOException e) {
      Logger.logException("Was unable to externalize JSPTranslator " + translator + //$NON-NLS-1$
          " to " + filePath, e); //$NON-NLS-1$
    }
  }

  /**
   * @param path {@link IPath} to the JSP file that the persisted translator is needed for
   * @return The persisted translator {@link File} for the JSP file at the given path
   * or <code>null</code> if no persisted translator exists for the JSP file at the given path
   */
  private static File getPersistedFile(IPath path) {
    return new File(getPersistedTranslatorFilePath(path.toString()));
  }
}
TOP

Related Classes of org.eclipse.jst.jsp.core.internal.java.JSPTranslatorPersister

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.