Package org.eclipse.jst.jsf.core.internal.jsflibraryconfig

Source Code of org.eclipse.jst.jsf.core.internal.jsflibraryconfig.JSFLibraryRegistryUtil

/*******************************************************************************
* Copyright (c) 2006 Oracle Corporation.
* 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:  Oracle
*******************************************************************************/
package org.eclipse.jst.jsf.core.internal.jsflibraryconfig;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFLibraryClasspathContainer;
import org.eclipse.jst.jsf.core.internal.Messages;
import org.eclipse.jst.jsf.core.internal.RegistryUpgradeCommitHandler;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.ArchiveFile;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibrary;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibraryRegistry;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibraryRegistryFactory;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.adapter.MaintainDefaultImplementationAdapter;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.impl.JSFLibraryRegistryPackageImpl;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.util.JSFLibraryRegistryResourceFactoryImpl;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.util.JSFLibraryRegistryResourceImpl;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.util.JSFLibraryRegistryUpgradeUtil;
import org.eclipse.jst.jsf.core.jsflibraryconfiguration.JSFLibraryConfigurationHelper;
import org.eclipse.jst.jsf.core.jsflibraryregistry.PluginProvidedJSFLibraryCreationHelper;
import org.eclipse.jst.jsf.core.jsflibraryregistry.internal.PluginProvidedJSFLibraryCreationHelper2;

/**
* A singleton maintains lists of implementation and component libraries
* in registry.
*  
* Each item in the lists contains a workingcopy of a JSF library and
* decorates with usage information such selection and deployment. 
*
* The lists are updated when there are changes in JSF library registry.
*
* @author Justin Chen, etc. - Oracle
* @deprecated
*/
public class JSFLibraryRegistryUtil {
  private static JSFLibraryRegistryUtil instance = null
 
  private List implLibs = null;
  private List compLibs = null;
 

  // The NS URI of the JSF Library Registry's Ecore package. (Must match
  // setting on package in Ecore model.)
  private static final String JSF_LIBRARY_REGISTRY_NSURI = "http://www.eclipse.org/webtools/jsf/schema/jsflibraryregistry.xsd"; //$NON-NLS-1$

  private static final String LIB_EXT_PT     = "pluginProvidedJsfLibraries"; //$NON-NLS-1$
  //deprecated ext-pt
  private static final String OLD_LIB_EXT_PT   = "jsfLibraries"; //$NON-NLS-1$

  // The JSF Library Registry EMF resource instance.
  private static JSFLibraryRegistryResourceImpl jsfLibraryRegistryResource = null;
 
  //JSFLibraryRegistry singleton
  private JSFLibraryRegistry jsfLibraryRegistry;
 
  /**
   * Private constructor
   */
  private JSFLibraryRegistryUtil() {
      //nothing to do
  }
 
  /**
   * Return the singleton instance of JSFLibraryRegistryUtil.
   *  
   * @return JSFLibraryRegistryUtil
   */
  public synchronized static JSFLibraryRegistryUtil getInstance() {
    if ( instance == null ) {
      instance = new JSFLibraryRegistryUtil();
      instance.loadJSFLibraryRegistry();
    }
    return instance;
  }

  /**
   * Convenience method to return the JSFLibraryRegistry instance.
   *
   * @return jsfLibReg JSFLibraryRegistry
   */
  public JSFLibraryRegistry getJSFLibraryRegistry() {
    return jsfLibraryRegistry;
  }
 
  /**
   * Get the default JSF implementation library instance.
   * A null is returned when there is no libraries in the registry.
   *
   * @return JSFLibraryInternalReference
   */
  public JSFLibraryInternalReference getDefaultJSFImplementationLibrary() {
    JSFLibrary dftImplLib = getJSFLibraryRegistry().getDefaultImplementation();
   
    return ((dftImplLib != null) ?
        getJSFLibraryReferencebyID(dftImplLib.getID()) :
        null);
  }
 
  /**
   * Get the working copy of JSF implementation libraries.
   * The list is updated when there are changes in registry.
   *
   * @return List
   */
  List getJSFImplementationLibraries() {
    if (implLibs == null) {
      implLibs = wrapJSFLibraries(getJSFLibraryRegistry().getImplJSFLibraries());
    } else {
      if (implLibs.size() != getJSFLibraryRegistry().getImplJSFLibraries().size() ||
          isAnyLibraryChanged(implLibs)) {
        implLibs.clear();
        implLibs = wrapJSFLibraries(getJSFLibraryRegistry().getImplJSFLibraries());
      }
    }
    return implLibs;
  }
   
  /**
   * Get the working copy of JSF component libraries.
   * The list is updated when there are changes in registry.
   *
   * @return List
   */
  List getJSFComponentLibraries() {
    if (compLibs == null) {
      compLibs = wrapJSFLibraries(getJSFLibraryRegistry().getNonImplJSFLibraries());
    } else {
      if (compLibs.size() != getJSFLibraryRegistry().getNonImplJSFLibraries().size() ||
          isAnyLibraryChanged(compLibs)) {
        compLibs.clear();
        compLibs = wrapJSFLibraries(getJSFLibraryRegistry().getNonImplJSFLibraries());
      }     
    }
    return compLibs;
  }
 
  /**
   * Get the JSFLibraryDecorator object from the provided ID.
   * A null is returned no library matches the ID.
   *
   * @param id String
   * @return JSFLibraryDecorator
   */
  public JSFLibraryInternalReference getJSFLibraryReferencebyID(final String id) {
    Iterator it = getJSFImplementationLibraries().iterator();
    JSFLibraryInternalReference crtItem = null;
   
    // search implementation libraries
    while(it.hasNext()) {
      crtItem = (JSFLibraryInternalReference)it.next();
      if (id.equals(crtItem.getID())) {
        return crtItem;
      }
    }
    // search component libraries
    it = getJSFComponentLibraries().iterator();
    while(it.hasNext()) {
      crtItem = (JSFLibraryInternalReference)it.next();
      if (id.equals(crtItem.getID())) {
        return crtItem;
      }
    }
    return null;
  }

  /**
   * Add a JSF Library into collection for either
   * JSF implementation libraries or component libraries. 
   * The decision is based on if a JSF library is an implementation.
   *
   * @param library JSFLibraryLibraryReference
   */
  public void addJSFLibrary(final JSFLibraryInternalReference library) {
     // Library is added only if it does not exist in registry
    if (library != null && getJSFLibraryRegistry().getJSFLibraryByID(library.getID()) == null) {
      // Add the library working copy into workspace registry.
      JSFLibrary jsfLib = library.getLibrary();
      getJSFLibraryRegistry().addJSFLibrary(jsfLib.getWorkingCopy());
     
      // Add library into the collection depends on its type.
      List list = (library.isImplementation() ?
              getJSFImplementationLibraries() :
              getJSFComponentLibraries());
      list.add(library);
    }
  } 
 
  private List wrapJSFLibraries(final EList libs) {
    List list = new ArrayList();
    if (libs != null) {
      JSFLibrary jsfLib;
      JSFLibraryInternalReference jsfLibDctr;
     
      Iterator it = libs.iterator();
      while (it.hasNext()) {
        jsfLib = (JSFLibrary) it.next();
         // Set unselected and undeployed initially.
        jsfLibDctr = new JSFLibraryInternalReference(jsfLib, //.getWorkingCopy(),
                false,
                false);
        list.add(jsfLibDctr);
      }
    } 
    return list;   
  }

  private boolean isAnyLibraryChanged(final List list) {
    Iterator it = list.iterator();
    JSFLibraryInternalReference wclib = null;    // working copy library
    JSFLibrary lib = null;
   
    while(it.hasNext()) {
      wclib = (JSFLibraryInternalReference)it.next();
      lib = getJSFLibraryRegistry().getJSFLibraryByID(wclib.getID());
      if (lib == null) {          // removed. Hence, changed.
        return true;
      }
      if (wclib.getArchiveFiles().size() !=
        lib.getArchiveFiles().size()) { // Archives changed..
        return true;
      }
      if (isAnyArchiveFileChanged(wclib.getArchiveFiles(),
          lib.getArchiveFiles())) {   // Check archive file changes.  I.e., name and location
        return true;
      }
    }
    return false;
  }

  private boolean isAnyArchiveFileChanged(final EList source, EList target) {   
    ArchiveFile arSrc = null;
    Iterator it = source.iterator();
    while (it.hasNext()) {
      arSrc = (ArchiveFile) it.next();
      if (!findMatchedArchive(arSrc, target)) {
        return true;
      }
    }
    return false;
  }
 
  private boolean findMatchedArchive(ArchiveFile source, EList list) {
    ArchiveFile target = null;
    Iterator it = list.iterator();
    while (it.hasNext()) {
      target = (ArchiveFile) it.next();
      if (target.equals(source)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Get the classpath entries for a JSF Library
   * @param lib
   * @return IClasspathEntry[]
   */
  public IClasspathEntry[] getClasspathEntries(JSFLibrary lib){   
    //TODO: cache to optimize.   probably belongs inside JSFLibrary model.
    ArrayList res= new ArrayList(lib.getArchiveFiles().size());
    for (Iterator it=lib.getArchiveFiles().iterator();it.hasNext();) {
      ArchiveFile jar= (ArchiveFile)it.next();     
      if (jar != null && jar.exists()) {
        IClasspathEntry entry = getClasspathEntry(jar);
        if (entry != null)
          res.add(entry);
      }
    }
    IClasspathEntry[] entries= (IClasspathEntry[]) res.toArray(new IClasspathEntry[res.size()]);
    return entries;
  }
 
  /**
   * Create IClasspathEntry for ArchiveFile
   * @param jar
   * @return IClasspathEntry
   */
  public IClasspathEntry getClasspathEntry(ArchiveFile jar){
    IClasspathEntry entry = null;
    if (jar !=null && jar.exists()){
      entry = JavaCore.newLibraryEntry(new Path(jar.getResolvedSourceLocation()), null, null);//, nu, sourceAttachRoot, accessRules, extraAttributes, false/*not exported*/);
    }
    return entry;
  }
 
  /**
   * Binds JSF Libraries to classpath containers when the library changes.
   *
   * This method will deal with library/cp container renames by removing the old classpath container and then adding.
   *
   * @param oldId
   * @param newId
   * @param monitor
   * @throws JavaModelException
   */
  public static void rebindClasspathContainerEntries(String oldId, String newId, IProgressMonitor monitor) throws JavaModelException {
    IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
    IJavaProject[] projects= JavaCore.create(root).getJavaProjects();
    IPath containerPath= new Path(JSFLibraryConfigurationHelper.JSF_LIBRARY_CP_CONTAINER_ID).append(newId);
    IPath oldContainerPath = new Path(JSFLibraryConfigurationHelper.JSF_LIBRARY_CP_CONTAINER_ID).append(oldId);
   
    JSFLibrary lib = JSFLibraryRegistryUtil.getInstance().getJSFLibraryRegistry().getJSFLibraryByID(newId);
    List affectedProjects= new ArrayList();
    boolean removeAndAddBecauseOfRename = (!oldId.equals(newId));
    // find all projects using the old container name...
    for (int i= 0; i < projects.length; i++) {
      IJavaProject project= projects[i];
      IClasspathEntry[] entries= project.getRawClasspath();
      for (int k= 0; k < entries.length; k++) {
        IClasspathEntry curr= entries[k];
        if (curr.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
          if (oldContainerPath.equals(curr.getPath())) {
            affectedProjects.add(project);
            break;
          }       
        }
      }
    }
   
    if (!affectedProjects.isEmpty()) {
      IJavaProject[] affected= (IJavaProject[]) affectedProjects.toArray(new IJavaProject[affectedProjects.size()]);
      IClasspathContainer[] containers= new IClasspathContainer[affected.length];
      removeAndAddBecauseOfRename = (!oldId.equals(newId));
      if (removeAndAddBecauseOfRename){//not very pretty... remove and add new container       
        IClasspathEntry newEntry = JavaCore.newContainerEntry(containerPath);
        for (int i= 0; i < affected.length; i++) {
          IJavaProject project= affected[i];
          IClasspathEntry[] entries= project.getRawClasspath();
          List keptEntries = new ArrayList();
          //keep all entries except the old one
          for (int k= 0; k < entries.length; k++) {
            IClasspathEntry curr= entries[k];
            if (curr.getEntryKind() == IClasspathEntry.CPE_CONTAINER){
                if( ! oldContainerPath.equals(curr.getPath()))
              keptEntries.add(curr);           
            }
            else {
              keptEntries.add(curr);
            }           
          }
          // add new container entry
          keptEntries.add(newEntry);
          setRawClasspath(project, keptEntries, monitor);
        }
       
      }
      else {//rebind

        JSFLibraryClasspathContainer container= new JSFLibraryClasspathContainer(lib);
        containers[0] = container;
 
        JavaCore.setClasspathContainer(containerPath, affected, containers, monitor);
      }
    } else {
      if (monitor != null) {
        monitor.done();
      }
    }
  }

  /**
   * Sets the raw classpath on a project and logs an error if it when a JavaModelException occurs
   * @param project
   * @param cpEntries
   * @param monitor
   */
  public static void setRawClasspath(IJavaProject project, List cpEntries, IProgressMonitor monitor) {
    IClasspathEntry[] entries = (IClasspathEntry[])cpEntries.toArray(new IClasspathEntry[0]);
    try {
      project.setRawClasspath(entries, monitor);
    } catch (JavaModelException e) {
      JSFCorePlugin.log(e, "Unable to set classpath for: "+project.getProject().getName()); //$NON-NLS-1$
    }
  }
 
  /**
   * Loads the JSFLibraryRegistry EMF object from plugin-specfic workspace
   * settings location.
   */
  private void loadJSFLibraryRegistry() {
    try {
     
      EPackage.Registry.INSTANCE.put(JSF_LIBRARY_REGISTRY_NSURI, JSFLibraryRegistryPackageImpl.init());
      URI jsfLibRegURI = JSFLibraryRegistryUpgradeUtil.getRegistryURI(JSFLibraryRegistryUpgradeUtil.JSF_LIBRARY_REGISTRY_LATESTVERSION_URL);     
      JSFLibraryRegistryUpgradeUtil.getInstance().upgradeRegistryIfNecessary(JSFLibraryRegistryUpgradeUtil.LATESTVERSION);

      JSFLibraryRegistryResourceFactoryImpl resourceFactory = new JSFLibraryRegistryResourceFactoryImpl();
      jsfLibraryRegistryResource = (JSFLibraryRegistryResourceImpl)resourceFactory.createResource(jsfLibRegURI);
      try {
        Map options = new HashMap();
        //disable notifications during load to avoid changing stored default implementation
        options.put(XMLResource.OPTION_DISABLE_NOTIFY, Boolean.TRUE);
        jsfLibraryRegistryResource.load(options);
        jsfLibraryRegistry = (JSFLibraryRegistry)jsfLibraryRegistryResource.getContents().get(0);
        
        loadJSFLibraryExtensions();
        loadDeprecatedJSFLibraryExtensions();//to be removed
       
      } catch(IOException ioe) {
        //Create a new Registry instance
        jsfLibraryRegistry = JSFLibraryRegistryFactory.eINSTANCE.createJSFLibraryRegistry();
        jsfLibraryRegistryResource = (JSFLibraryRegistryResourceImpl)resourceFactory.createResource(jsfLibRegURI);
        jsfLibraryRegistryResource.getContents().add(jsfLibraryRegistry);
        loadJSFLibraryExtensions();
        loadDeprecatedJSFLibraryExtensions();//to be removed
        saveJSFLibraryRegistry();
      }
      //add adapter to maintain default implementation
      if (jsfLibraryRegistry != null) {       
        //check that a default impl is set.   if not pick first one if available.
        JSFLibrary defLib = jsfLibraryRegistry.getDefaultImplementation();
        if (defLib == null && jsfLibraryRegistry.getImplJSFLibraries().size() > 0){
          jsfLibraryRegistry.setDefaultImplementation((JSFLibrary)jsfLibraryRegistry.getImplJSFLibraries().get(0));
          saveJSFLibraryRegistry();
        }
        jsfLibraryRegistry.eAdapters().add(MaintainDefaultImplementationAdapter.getInstance());
       
        //commit
        RegistryUpgradeCommitHandler.commitMigrationIfNecessary();
      }
    } catch(MalformedURLException mue) {
      JSFCorePlugin.log(IStatus.ERROR, Messages.JSFLibraryRegistry_ErrorCreatingURL, mue);
    }
  }
/////////////////////////////////   Load and Save JSF Library Registry ////////////////////////////////////////////////
 
  /**
   * Creates library registry items from extension points.
   */
  private void loadJSFLibraryExtensions() {
    try {
      IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(JSFCorePlugin.PLUGIN_ID, LIB_EXT_PT);
      IExtension[] extensions = point.getExtensions();
      for (int i=0;i < extensions.length;i++){
        IExtension ext = extensions[i];
        for (int j=0;j < ext.getConfigurationElements().length;j++){
          PluginProvidedJSFLibraryCreationHelper2 newLibCreator = new PluginProvidedJSFLibraryCreationHelper2(ext.getConfigurationElements()[j]);           
          JSFLibrary newLib = newLibCreator.create();
         
          /**
           * Additional check on if a plug-in contributes jsflibraries is an expanded folder.
           * Fix related to bug 144954. 
           *
           * It would be ideal to check if a plug-in is distributed as a JAR
           * before a JSFLibrary is created.
           *
           * This is a temporary solution since JARs in a JAR case is not
           * supported in this release.  Bug 14496.
           */
          if (newLib != null) //&& isJSFLibinExpandedFolder(newLib))
            jsfLibraryRegistry.addJSFLibrary(newLib);
        }
      }
    } catch (InvalidRegistryObjectException e) {
      JSFCorePlugin.log(IStatus.ERROR, Messages.JSFLibraryRegistry_ErrorLoadingFromExtPt, e);
    }
  }
 
  /**
   * Creates deprecated library registry items from extension points.
   * TO BE REMOVED
   */
  private void loadDeprecatedJSFLibraryExtensions() {
    try {
      IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(JSFCorePlugin.PLUGIN_ID, OLD_LIB_EXT_PT);
      IExtension[] extensions = point.getExtensions();
      for (int i=0;i < extensions.length;i++){
        IExtension ext = extensions[i];
        for (int j=0;j < ext.getConfigurationElements().length;j++){
          PluginProvidedJSFLibraryCreationHelper newLibCreator = new PluginProvidedJSFLibraryCreationHelper(ext.getConfigurationElements()[j]);           
          JSFLibrary newLib = newLibCreator.create();
         
          /**
           * Additional check on if a plug-in contributes jsflibraries is an expanded folder.
           * Fix related to bug 144954. 
           *
           * It would be ideal to check if a plug-in is distributed as a JAR
           * before a JSFLibrary is created.
           *
           * This is a temporary solution since JARs in a JAR case is not
           * supported in this release.  Bug 14496.
           */
          if (newLib != null ) //&& isJSFLibinExpandedFolder(newLib))
            jsfLibraryRegistry.addJSFLibrary(newLib);
        }
      }
    } catch (InvalidRegistryObjectException e) {
      JSFCorePlugin.log(IStatus.ERROR, Messages.JSFLibraryRegistry_ErrorLoadingFromExtPt, e);
    }
  }
 
  /**
   * Saves the JSFLibraryRegistry EMF object from plugin-specfic workspace
   * settings location. (Called from stop(BundleContext).)
   * @return true if save is successful
   */
  public boolean saveJSFLibraryRegistry() {
    boolean saved = false;
    if (jsfLibraryRegistryResource != null) {
      try {
        jsfLibraryRegistryResource.save(Collections.EMPTY_MAP);
        saved = true;
      } catch(IOException ioe) {
        JSFCorePlugin.log(IStatus.ERROR, Messages.JSFLibraryRegistry_ErrorSaving, ioe);
      }
    } else {
      JSFCorePlugin.log(IStatus.ERROR, Messages.JSFLibraryRegistry_ErrorSaving);
    }
    return saved;
  }


}
TOP

Related Classes of org.eclipse.jst.jsf.core.internal.jsflibraryconfig.JSFLibraryRegistryUtil

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.