Package org.objectstyle.wolips.eomodeler.factories

Source Code of org.objectstyle.wolips.eomodeler.factories.EclipseProjectEOModelGroupFactory

package org.objectstyle.wolips.eomodeler.factories;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.objectstyle.woenvironment.env.WOEnvironment;
import org.objectstyle.woenvironment.plist.PropertyListParserException;
import org.objectstyle.woenvironment.plist.SimpleParserDataStructureFactory;
import org.objectstyle.woenvironment.plist.WOLPropertyListSerialization;
import org.objectstyle.wolips.baseforplugins.util.StringUtils;
import org.objectstyle.wolips.baseforplugins.util.URLUtils;
import org.objectstyle.wolips.eomodeler.core.model.AbstractManifestEOModelGroupFactory;
import org.objectstyle.wolips.eomodeler.core.model.ManifestSearchFolder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class EclipseProjectEOModelGroupFactory extends AbstractManifestEOModelGroupFactory {
  @Override
  public List<ManifestSearchFolder> getSearchFolders(File selectedModelFolder) throws IOException {
    // System.out.println(
    // "EclipseProjectEOModelGroupFactory.getSearchFolders: Looking for Eclipse projects ..."
    // );
    List<ManifestSearchFolder> searchFolders = null;
    List<File> eclipseProjectFolders = new LinkedList<File>();
    try {
      findEclipseProjectFolders(selectedModelFolder, eclipseProjectFolders);
    } catch (PropertyListParserException e) {
      e.printStackTrace();
      throw new IOException("Failed to parse '.EntityModeler.plist'. " + StringUtils.getErrorMessage(e));
    }
    if (!eclipseProjectFolders.isEmpty()) {
      searchFolders = new LinkedList<ManifestSearchFolder>();
      for (File eclipseProjectFolder : eclipseProjectFolders) {
        // System.out.println(
        // "EclipseProjectEOModelGroupFactory.getSearchFolders: Project = "
        // + eclipseProjectFolder);
        Set<File> visitedProjectFolders = new HashSet<File>();
        try {
          processEclipseProject(eclipseProjectFolder, searchFolders, visitedProjectFolders, new WOEnvironment());
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    // System.out.println(
    // "EclipseProjectEOModelGroupFactory.getSearchFolders: " +
    // searchFolders);
    return searchFolders;
  }

  protected File getWorkspaceFolder(File projectFolder) {
    File workspaceFolder;
    String workspaceFolderPath = System.getProperty("workspaceFolder");
    if (workspaceFolderPath != null) {
      workspaceFolder = new File(workspaceFolderPath);
    } else {
      workspaceFolder = null;
      File searchingFolder = projectFolder;
      while (searchingFolder != null && workspaceFolder == null) {
        File tempFolder = new File(searchingFolder, ".metadata");
        if (tempFolder.exists() && tempFolder.isDirectory()) {
          workspaceFolder = searchingFolder;
        } else {
          searchingFolder = searchingFolder.getParentFile();
        }
      }
    }

    if (workspaceFolder == null) {
      workspaceFolder = projectFolder.getParentFile();
    }

    return workspaceFolder;
  }

  protected File getProjectFolder(File workspaceFolder, String projectName) {
    File projectFolder = null;
    File projectLocationFile = new File(workspaceFolder, ".metadata/.plugins/org.eclipse.core.resources/.projects/" + projectName + "/.location");
    if (projectLocationFile.exists()) {
      // MS: This is pretty crazy, but the .location file is a binary file (of "unknown" layout) that contains
      // a URL that is the location of the project folder.  We're going to load that binary file and look for
      // something that looks like a file: URL ... Crazy but works :)
      try {
        FileInputStream fis = new FileInputStream(projectLocationFile);
        try {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          byte[] buffer = new byte[2048];
          while (fis.available() > 0) {
            int bytesRead = fis.read(buffer);
            baos.write(buffer, 0, bytesRead);
          }
          String locationContents = baos.toString();
          int fileIndex = locationContents.indexOf("file:");
          if (fileIndex != -1) {
            int zeroIndex = locationContents.indexOf(0, fileIndex);
            String projectPath = locationContents.substring(fileIndex, zeroIndex);
            projectFolder = URLUtils.cheatAndTurnIntoFile(new URL(projectPath));
          }
        } finally {
          fis.close();
        }
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    if (projectFolder == null) {
      projectFolder = new File(workspaceFolder, projectName);
    }
    return projectFolder;
  }

  protected void processEclipseProject(File eclipseProjectFolder, List<ManifestSearchFolder> searchFolders, Set<File> visitedProjects, WOEnvironment env) throws IOException, XPathExpressionException, SAXException, ParserConfigurationException {
    if (eclipseProjectFolder == null || !eclipseProjectFolder.exists() || visitedProjects.contains(eclipseProjectFolder)) {
      return;
    }
    // System.out.println(
    // "EclipseProjectEOModelGroupFactory.processEclipseProject: Project folder '"
    // + eclipseProjectFolder + "' ...");

    String[] buildFolderNames = new String[] { "build", "dist" };
    for (String buildFolderName : buildFolderNames) {
      File buildFolder = new File(eclipseProjectFolder, buildFolderName);
      if (buildFolder.exists()) {
        File buildResourcesFolder;
        File frameworkResourcesFolder = new File(buildFolder, eclipseProjectFolder.getName() + ".framework" + File.separator + "Resources");
        if (frameworkResourcesFolder.exists()) {
          buildResourcesFolder = frameworkResourcesFolder;
        } else {
          File woaResourcesFolder = new File(buildFolder, eclipseProjectFolder.getName() + ".woa" + File.separator + "Contents" + File.separator + "Resources");
          if (woaResourcesFolder.exists()) {
            buildResourcesFolder = woaResourcesFolder;
          } else {
            buildResourcesFolder = buildFolder;
          }
        }
        // We're cheating some here and forcing project build resources
        // folders to the front of the line ...
        searchFolders.add(0, new ManifestSearchFolder(buildResourcesFolder));
        break;
      }
    }
    visitedProjects.add(eclipseProjectFolder);

    File workspaceFolder = null;
    File eclipseClasspathFile = new File(eclipseProjectFolder, ".classpath");
    if (eclipseClasspathFile.exists()) {
      XPathExpression eclipseClasspathEntryExpression = XPathFactory.newInstance().newXPath().compile("//classpath/classpathentry");
      Document eclipseClasspathDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(eclipseClasspathFile);
      NodeList eclipseClasspathEntryNodes = (NodeList) eclipseClasspathEntryExpression.evaluate(eclipseClasspathDocument, XPathConstants.NODESET);
      for (int eclipseClasspathEntryNum = 0; eclipseClasspathEntryNum < eclipseClasspathEntryNodes.getLength(); eclipseClasspathEntryNum++) {
        Element eclipseClasspathEntryElement = (Element) eclipseClasspathEntryNodes.item(eclipseClasspathEntryNum);
        String kind = eclipseClasspathEntryElement.getAttribute("kind");
        String path = eclipseClasspathEntryElement.getAttribute("path");
        if ("src".equals(kind) && path != null && path.startsWith("/")) {
          if (workspaceFolder == null) {
            workspaceFolder = getWorkspaceFolder(eclipseProjectFolder);
          }
          File referencedProjectFolder = getProjectFolder(workspaceFolder, path).getCanonicalFile();
            //new File(eclipseProjectFolder.getParentFile(), path).getCanonicalFile();
          processEclipseProject(referencedProjectFolder, searchFolders, visitedProjects, env);
        } else if ("con".equals(kind) && path != null && path.startsWith("org.objectstyle.wolips.ContainerInitializer/")) {
          String[] strs = path.split("/");
          List<String> frameworkNames = new LinkedList<String>();
          for (int i = 3; i < strs.length; i += 11) {
            frameworkNames.add(strs[i]);
          }
          loadFrameworks(frameworkNames.toArray(new String[frameworkNames.size()]), searchFolders, visitedProjects, env);
        } else if ("con".equals(kind) && path != null && path.startsWith("org.objectstyle.wolips.WO_CLASSPATH/")) {
          String[] frameworkNames = path.split("/");
          loadFrameworks(frameworkNames, searchFolders, visitedProjects, env);
        } else if ("con".equals(kind) && path != null && path.startsWith("WOFramework/")) {
          String frameworkName = path.substring(path.indexOf("/") + 1);
          if (workspaceFolder == null) {
            workspaceFolder = getWorkspaceFolder(eclipseProjectFolder);
          }
          File referencedProjectFolder = getProjectFolder(workspaceFolder, frameworkName).getCanonicalFile();
          if (referencedProjectFolder.exists()) {
            processEclipseProject(referencedProjectFolder, searchFolders, visitedProjects, env);
          }
          else {
            loadFrameworks(new String[] { frameworkName }, searchFolders, visitedProjects, env);
          }
        }
      }
    }
  }

  protected void loadFrameworks(String[] frameworkNames, List<ManifestSearchFolder> searchFolders, Set<File> visitedProjects, WOEnvironment env) throws IOException {
    File userFrameworksFolder = new File(env.getWOVariables().userFrameworkPath());
    File localFrameworksFolder = new File(env.getWOVariables().localFrameworkPath());
    File systemFrameworksFolder = new File(env.getWOVariables().systemFrameworkPath());
    for (int frameworkNum = 1; frameworkNum < frameworkNames.length; frameworkNum++) {
      String frameworkFolderName = frameworkNames[frameworkNum] + ".framework";
      File matchingFrameworkFolder = null;
      File userFrameworkFolder = new File(userFrameworksFolder, frameworkFolderName);
      if (userFrameworkFolder.exists()) {
        matchingFrameworkFolder = userFrameworkFolder.getCanonicalFile();
      } else {
        File localFrameworkFolder = new File(localFrameworksFolder, frameworkFolderName);
        if (localFrameworkFolder.exists()) {
          matchingFrameworkFolder = localFrameworkFolder.getCanonicalFile();
        } else {
          File systemFrameworkFolder = new File(systemFrameworksFolder, frameworkFolderName);
          if (systemFrameworkFolder.exists()) {
            matchingFrameworkFolder = systemFrameworkFolder.getCanonicalFile();
          }
        }
      }
      if (matchingFrameworkFolder != null && !visitedProjects.contains(matchingFrameworkFolder)) {
        // System.out.println(
        // "EclipseProjectEOModelGroupFactory.processEclipseProject: framework = "
        // + matchingFrameworkFolder);
        ManifestSearchFolder searchFolder = new ManifestSearchFolder(new File(matchingFrameworkFolder, "Resources"));
        if (!searchFolders.contains(searchFolder)) {
          searchFolders.add(searchFolder);
       
        visitedProjects.add(matchingFrameworkFolder);
      }
    }

  }

  @SuppressWarnings("unchecked")
  protected void findEclipseProjectFolders(File folder, List<File> eclipseProjectFolders) throws IOException, PropertyListParserException {
    if (folder != null) {
      boolean foundProjectFolders = false;
      if (folder.isDirectory()) {
        // System.out.println(
        // "EclipseProjectEOModelGroupFactory.findEclipseProjectFolders: Looking for '"
        // + folder + "' ...");
        File projectLocator = new File(folder, ".EntityModeler.plist");
        if (projectLocator.exists()) {
          // System.out.println(
          // "EclipseProjectEOModelGroupFactory.findEclipseProjectFolders:   Found project locator '"
          // + projectLocator + "' ...");
          Map<String, Object> projectProperties = (Map<String, Object>) WOLPropertyListSerialization.propertyListWithContentsOfFile(projectLocator.getCanonicalPath(), new SimpleParserDataStructureFactory());
          Map<String, List<String>> dependencies = (Map<String, List<String>>) projectProperties.get("Dependencies");
          if (dependencies != null) {
            List<String> projectFilePaths = dependencies.get("Eclipse");
            if (projectFilePaths != null) {
              for (String projectFilePath : projectFilePaths) {
                File projectFolder = new File(projectFilePath);
                if (!projectFolder.exists()) {
                  projectFolder = new File(folder, projectFilePath);
                }
                if (projectFolder.exists()) {
                  projectFolder = projectFolder.getCanonicalFile();
                  if (isEclipseProjectFolder(projectFolder)) {
                    // System.out.println(
                    // "EclipseProjectEOModelGroupFactory.findEclipseProjectFolders:     Found project '"
                    // + projectFolder + "'");
                    eclipseProjectFolders.add(projectFolder);
                    foundProjectFolders = true;
                  }
                }
              }
            }
          }
        } else if (isEclipseProjectFolder(folder)) {
          // System.out.println(
          // "EclipseProjectEOModelGroupFactory.findEclipseProjectFolders:   Found project '"
          // + folder + "'");
          File eclipseProjectFolder = folder.getCanonicalFile();
          eclipseProjectFolders.add(eclipseProjectFolder);
          foundProjectFolders = true;
        }
      }
      if (!foundProjectFolders) {
        File parentFolder = folder.getParentFile();
        findEclipseProjectFolders(parentFolder, eclipseProjectFolders);
      }
    }
  }

  public boolean isEclipseProjectFolder(File folder) {
    return new File(folder, ".project").exists() && new File(folder, ".classpath").exists();
  }

}
TOP

Related Classes of org.objectstyle.wolips.eomodeler.factories.EclipseProjectEOModelGroupFactory

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.