Package org.cloudfoundry.ide.eclipse.server.standalone.internal.application

Source Code of org.cloudfoundry.ide.eclipse.server.standalone.internal.application.StandaloneModuleDelegate

/*******************************************************************************
* Copyright (c) 2012, 2014 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License,
* Version 2.0 (the "License�); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*  Contributors:
*     Pivotal Software, Inc. - initial API and implementation
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.standalone.internal.application;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryProjectUtil;
import org.cloudfoundry.ide.eclipse.server.standalone.internal.startcommand.JavaStartCommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
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.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.model.IModuleResource;
import org.eclipse.wst.server.core.util.ModuleFile;
import org.eclipse.wst.server.core.util.ModuleFolder;
import org.eclipse.wst.server.core.util.ProjectModule;

/**
* The module delegate maps WTP module resources to the specified project's
* resources. For standalone apps, all project files and folders are mapped to
* corresponding module resources. If additional filtering is required, it can
* be done by overriding module resource member getters from the parent class.
* <p/>
* The delegate gets invoked indirectly by WTP through an IModule created by the
* Module factory, when it is adapted to a Module delegate.
* <p/>
* This may occur when a request is made for IModuleResource for all the
* resources in a project , and this request may typically happen only when
* publishing or updating the resources of a project
* <p/>
* Note that when a IModule is created by the module factory, a reference to
* that factory is passed into the IModule. The factory then is responsible for
* creating a module delegate, when a module delegate is requested via an
* adapter call to the IModule.
* <p/>
* Note also that module resources for corresponding local resources are created
* recursively, and the list of module resources generated are root level module
* resources that may contain child members. THe list of module resources is not
* a flat list, and root level folder module resources may have child members.
* Consequently, when handling the list of generated module resources, it should
* be done recursively.
* <p/>
* See implementations of IModule
*
* @see StandAloneModuleFactory
* @see IModule
* @deprecated As of CF 1.6.0 Java applications are now packaged into jars prior to deployment to Cloud Foundry. See {@link JavaCloudFoundryArchiver}
*/
public class StandaloneModuleDelegate extends ProjectModule {

  public StandaloneModuleDelegate(IProject project) {
    super(project);
  }

  /**
   * Generates module resources for the given resource location. If the
   * resource location is a workspace folder or project, module resources for
   * all of its children are also generated recursively. The relative module
   * resource path is the path where the resource should be published
   * remotely, and it need not match the relative or absolute local resource
   * location. Therefore a resource in
   * /Users/myuser/workspace/myproject/myfolder maybe be published to /lib, so
   * remotely, myfolder will appear as /lib/myfolder. Although /lib need not
   * exist locally, it must have a corresponding module resource element.
   *
   * @param localResourceLocation
   * @param relativeModuleResourcePath
   * @return module resources for the given location, or null if module
   *         resources could not be resolved for the given location
   * @throws CoreException
   */
  protected IModuleResource[] collectResources(String localResourceLocation,
      IPath relativeModuleResourcePath) throws CoreException {

    IProject project = getProject();

    if (project.isAccessible()) {

      IPath projectPath = project.getLocation();

      // Handle the case where the resource location points to the project
      // itself
      if (projectPath != null
          && localResourceLocation.equals(projectPath.toOSString())) {
        return getModuleResources(relativeModuleResourcePath, project);
      } else {

        // Module resources should be mapped to corresponding workspace
        // resources, unless they are external files, at which point
        // they should be mapped to the external File.
        // At this stage, find workspace or File resources that
        // correspond to
        // the module resource to be created.

        // At this point, the path may be full or relative to a
        // workspace. The path may indicate
        // a resource outside the workspace as well, in particular
        // point to dependency jars outside of the
        // workspace. All these cases must be handled.
        IResource workspaceResource = null;
        IPath resourcePath = new Path(localResourceLocation);
        File publishableFile = resourcePath.toFile();

        // First see if it is a full path to an existing file.
        if (projectPath != null && publishableFile != null
            && publishableFile.exists()) {

          IPath relativeResourcepath = resourcePath
              .makeRelativeTo(projectPath);

          if (publishableFile.isFile()) {
            workspaceResource = project
                .getFile(relativeResourcepath);
          } else if (publishableFile.isDirectory()) {
            workspaceResource = project
                .getFolder(relativeResourcepath);
          }
        } else {
          // Otherwise check if the path is relative to the
          // workspace and it exists
          workspaceResource = ResourcesPlugin.getWorkspace()
              .getRoot().getFile(resourcePath);
          if (workspaceResource == null
              || !workspaceResource.exists()) {
            workspaceResource = ResourcesPlugin.getWorkspace()
                .getRoot().getFolder(resourcePath);
          }
        }

        // If the publishable workspace resource exists, create a
        // corresponding module resource for it
        if (workspaceResource != null && workspaceResource.exists()) {
          if (workspaceResource instanceof IContainer) {
            return getModuleResources(relativeModuleResourcePath,
                (IContainer) workspaceResource);
          } else if (workspaceResource instanceof IFile) {
            return new IModuleResource[] { new ModuleFile(
                (IFile) workspaceResource,
                workspaceResource.getName(),
                relativeModuleResourcePath) };
          }
        }
        // Others check if it is an external file
        else if (publishableFile != null && publishableFile.exists()
            && publishableFile.isFile()) {
          // Try creating a module if the file system file exists
          return new IModuleResource[] { new ModuleFile(
              publishableFile, publishableFile.getName(),
              relativeModuleResourcePath) };
        }
      }
    }

    return null;
  }

  @Override
  public IModuleResource[] members() throws CoreException {
    return computeRuntimeClasspathMembers();
  }

  protected IModuleResource[] computeRuntimeClasspathMembers()
      throws CoreException {
    List<IModuleResource> members = new ArrayList<IModuleResource>();

    IJavaProject javaProject = CloudFoundryProjectUtil
        .getJavaProject(getProject());

    if (javaProject != null) {
      StandaloneRuntimeResolver resolver = new StandaloneRuntimeResolver(
          javaProject, true);

      List<String> resolvedSource = resolver.getRuntimeSourceLocations();

      // Add the non-dependecy resources first at root level path. This
      // means that, when published,
      // these resources will be added at root level in the remote app
      // directory
      if (resolvedSource != null) {
        for (String path : resolvedSource) {
          addModuleResources(path, members, Path.EMPTY);
        }
      }

      // Add the dependencies in a /lib
      if (resolver.hasRuntimeDependencies()) {
        // check if at root level, there already exists a /lib folder
        ModuleFolder libFolder = createLibFolder(members);
        List<String> dependencies = resolver
            .getRuntimeDependencyLocations();
        List<IModuleResource> libMembers = new ArrayList<IModuleResource>();
        for (String path : dependencies) {
          addModuleResources(path, libMembers,
              JavaStartCommand.DEFAULT_LIB_PATH);
        }
        if (!libMembers.isEmpty()) {
          libFolder.setMembers(libMembers
              .toArray(new IModuleResource[0]));
        }
      }
    }
    return members.toArray(new IModuleResource[0]);
  }

  /**
   * Either returns an existing /lib folder at root level in the give list of
   * module resources, or creates one and adds it to the given list of module
   * resources. As a consequence, the passed list of module resources should
   * be the original list, and not a copy. Always returns a non-null /lib
   * folder that has been added to the given list of module resources
   *
   * @param moduleResources
   * @return non-null /lib folder
   */
  protected ModuleFolder createLibFolder(List<IModuleResource> moduleResources) {
    for (IModuleResource resource : moduleResources) {
      if (resource instanceof ModuleFolder
          && JavaStartCommand.DEFAULT_LIB_PATH.equals(resource
              .getName())) {
        return (ModuleFolder) resource;
      }
    }

    // Otherwise create one with a root level module relative path (i.e. an
    // empty path)
    org.eclipse.wst.server.core.util.ModuleFolder folder = new ModuleFolder(
        null, JavaStartCommand.DEFAULT_LIB, Path.EMPTY);
    moduleResources.add(folder);
    return folder;
  }

  /**
   * Generates module resources for the given local resource location, and
   * adds it to the give list of existing module resources. If the resource
   * location is a folder, all content of the folder will be recursively added
   * as child members of the folder. The module relative path is the relative
   * path associated with the resource, where the resource will be located
   * remotely.
   * <p/>
   * Example: if the local resource is a folder at
   * /Users/myuser/workspace/myproject/myfolder, and the relative module path
   * is specified as /lib, then A module resource folder for "myfolder",
   * containing all the content of myfolder as additional module resource
   * members, will be created, and when published, the folder will appear in
   * relative /lib path remotely, so the relative remote location will be
   * /lib/myfolder.
   *
   * <p/>
   *
   * Note that the module relative path MUST have a corresponding module
   * resource folder, if it is not an empty path, meaning that there must be a
   * corresponding module resource folder for it. In the example above, there
   * must be a module resource folder for "/lib", but it is not necessary for
   * it to actually exists locally, since module resources do not have to map
   * to actual local resources. If an empty path is specified, it means that
   * all the module resources created will be published at root level
   * relatively to the remote application directory.
   *
   * <p/>
   *
   * If the local resource whose module resource needs to be created should be
   * added at root level remotely, then an empty path should be passed as a
   * module relative path.
   *
   * @param resourceLocation
   *            resource location that needs to be mapped to corresponding
   *            module resources. location can be relative or absolute.
   * @param members
   *            where module resource should be added
   * @param moduleRelativePath
   *            remote location path of the resource. It does not need to be
   *            the same as the local resource location.
   * @throws CoreException
   */
  protected void addModuleResources(String resourceLocation,
      Collection<IModuleResource> members, IPath moduleRelativePath)
      throws CoreException {
    if (resourceLocation != null) {
      IModuleResource[] containerResources = collectResources(
          resourceLocation, moduleRelativePath);
      if (containerResources != null) {
        for (IModuleResource resource : containerResources) {
          if (resource != null && !members.contains(resource)) {
            members.add(resource);
          }
        }
      }
    }
  }

}
TOP

Related Classes of org.cloudfoundry.ide.eclipse.server.standalone.internal.application.StandaloneModuleDelegate

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.