Package nexj.core.build

Source Code of nexj.core.build.ProjectJarName

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.build;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Locale;

import nexj.core.meta.MetadataException;
import nexj.core.meta.xml.XMLMetadataHelper;
import nexj.core.meta.xml.XMLMetadataHelper.MixinNamespaceHandler;
import nexj.core.util.StringUtil;
import nexj.core.util.SysUtil;
import nexj.core.util.URLUtil;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.w3c.dom.Element;

/**
* Ant task for generating root and base JAR file names.
*/
public class ProjectJarName extends Task
{
   //constants
  
   private final static String NAMESPACE_ATTR = "namespace";
   private final static String BASE_NAMESPACE_ATTR = "baseNamespace";
   private final static String REVISION_ATTR = "revision";
   private final static String VERSION_ATTR = "version";
   private final static String BASE_VERSION_ATTR = "baseVersion";
   private final static String BASE_CHECKSUM_ATTR = "baseChecksum";
   private final static String JAR_PREFIX = "NEXJ-META-";

   //instances

   private String m_sSrcDir; //Workspace directory.
   private String m_sOutDir; //Publish directory.
   private String m_sBaseDir; //Base JAR location directory.
   private String m_sProject; //Name of the project to retrieve Jar file names for.
   private String m_sMetaJarProperty; //Ant property that stores the root Jar file name.
   private String m_sMetaDir; //Ant property that stores the metadata directory name.
   private String m_sMetaPathProperty; // Ant property that stores the root folder URI.
   private String m_sBaseJarProperty; //Ant property that stores the base Jar file name.
   private String m_sBasePathProperty; // Ant property that stores the base folder URI.
   private String m_sMixinJarsProperty; // Ant property that stores the mixin Jar URLs.
   private String m_sChecksumProperty; //Ant property that stores the checksum.
   private String m_sVersionProperty; //Ant property that stores the checksum.
   private String m_sRevisionProperty; //Ant property that stores the project revision.
   private String m_sBaseProjectProperty; //Ant property that stores the base project name.
   private boolean m_bProfileEnabled; //Ant property that stores whether to output timing info

   //operations

   /**
    * Ant attribute setter for project name.
    */
   public void setProject(String sProject)
   {
      m_sProject = sProject;
   }

   /**
    * Ant attribute setter for property to store generated root Jar file.
    */
   public void setMetaJarProperty(String sMetaJarProperty)
   {
      m_sMetaJarProperty = sMetaJarProperty;
   }

   /**
    * Ant attribute setter for property to store generated base Jar file.
    */
   public void setBaseJarProperty(String sBaseJarProperty)
   {
      m_sBaseJarProperty = sBaseJarProperty;
   }
  
   /**
    * Ant attribute setter for property to store generated root folder URI.
    */
   public void setMetaPathProperty(String sMetaPathProperty)
   {
      m_sMetaPathProperty = sMetaPathProperty;
   }

   /**
    * Ant attribute setter for property to store generated base folder URI.
    */
   public void setBasePathProperty(String sBasePathProperty)
   {
      m_sBasePathProperty = sBasePathProperty;
   }

   /**
    * Ant attribute setter for property to store base project name.
    */
   public void setBaseProjectProperty(String sBaseProjectProperty)
   {
      m_sBaseProjectProperty = sBaseProjectProperty;
   }

   /**
    * Ant attribute setter for property to store mixin repository URLs.
    */
   public void setMixinJarsProperty(String sMixinJarsProperty)
   {
      m_sMixinJarsProperty = sMixinJarsProperty;
   }

   /**
    * Ant attribute setter for property to store generated checksum.
    */
   public void setChecksumProperty(String sChecksumProperty)
   {
      m_sChecksumProperty = sChecksumProperty;
   }

   /**
    * Ant attribute setter for property to store the parsed version.
    */
   public void setVersionProperty(String sVersionProperty)
   {
      m_sVersionProperty = sVersionProperty;
   }

   /**
    * Ant attribute setter for property to store the parsed revision.
    */
   public void setRevisionProperty(String sRevisionProperty)
   {
      m_sRevisionProperty = sRevisionProperty;
   }

   /**
    * Ant attribute setter for workspace directory.
    */
   public void setSrcDir(String sSrcDir)
   {
      m_sSrcDir = sSrcDir;
   }

   /**
    * Ant attribute setter for publish directory.
    */
   public void setOutDir(String sOutDir)
   {
      m_sOutDir = sOutDir;
   }

   /**
    * Ant attribute setter for base JAR directory.
    */
   public void setBaseDir(String sBaseDir)
   {
      m_sBaseDir = sBaseDir;
   }

   /**
    * Ant attribute setter for base JAR directory.
    */
   public void setProfile(String sProfileEnabled)
   {
      m_bProfileEnabled = StringUtil.parseBoolean(sProfileEnabled);
   }

   /**
    * Ant attribute setter for property to store metadata directory if not default.
    */
   public void setMetaDir(String sMetaDir)
   {
      m_sMetaDir = sMetaDir;
   }

   /**
    * Generate path to the meta data folder.
    *
    * @param sProject name of the project.
    * @return The path to the meta data folder for the specified project.
    */
   private String getMetaDir(String sProject)
   {
      if (m_sMetaDir != null)
      {
         return m_sMetaDir;
      }
      else if (sProject.equals(".tmp"))
      {
         return m_sOutDir + "/nexj/meta";
      }
      else
     
         return m_sSrcDir + '/' + sProject + "/meta";
      }
   }

   /**
    * Get the name of the JAR file that has been built already.
    *
    * @param sProject name of the project.
    * @param sChecksum checksum of the meta files.
    * @return Name of the existing JAR file with the specified the version. If the
    *   file does not exist then return null.
    */
   private String getPublishedJARName(String sProject, String sChecksum)
   {
      File publishDir = new File(m_sBaseDir);

      if (publishDir.exists() && publishDir.isDirectory())
      {
         File[] files = publishDir.listFiles();

         sProject = '-' + sProject.toUpperCase(Locale.ENGLISH) + '-';
         sChecksum = '-' + sChecksum.toUpperCase(Locale.ENGLISH);

         for (int i = 0; i < files.length; ++i)
         {
            File file = files[i];

            if (file.isFile())
            {
               String sName = file.getName().toUpperCase(Locale.ENGLISH);
               int nExtStart = sName.lastIndexOf('.');

               if (sName.startsWith(JAR_PREFIX) && nExtStart > JAR_PREFIX.length())
               {
                  sName = sName.substring(JAR_PREFIX.length() - 1, nExtStart);

                  if(sName.startsWith(sProject) &&
                     sName.endsWith(sChecksum))
                  {
                     String sPath = file.getAbsolutePath();

                     log("Found: " + sPath);

                     return sPath;
                  }
               }
            }
         }
      }
      else
      {
         log("Unknown dir: "+ publishDir.getPath());
      }

      return null;
   }

   /**
    * Generate a JAR name based on given version information.
    *
    * @param sProject name of the project.
    * @param sRevision revision info of the project.
    * @param sVersion version info of the project.
    * @param sChecksum checksum of the meta files.
    * @return JAR file name based on the version information.
    */
   private String getJarName(String sProject, String sRevision, String sVersion, String sChecksum)
   {
      StringBuilder sb = new StringBuilder();

      if (m_sOutDir != null)
      {
         sb.append(m_sOutDir);
         sb.append(File.separatorChar);
      }

      sb.append("nexj-meta-");
      int nFileNameIndex = sb.length();
      sb.append(sProject);
      sb.append("-");
      sb.append(sRevision);
      sb.append("-");
      sb.append(sVersion);
      sb.append("-");
      sb.append(sChecksum);

      for (int i = nFileNameIndex; i < sb.length(); i++)
      {
         if (sb.charAt(i) == ' ')
         {
            sb.setCharAt(i, '_');
         }
      }

      sb.append(".jar");
      return sb.toString();
   }

   /**
    * Generate a JAR file names from the Metadata and set them into Ant properties.
    *
    * @param sProject name of the project.
    */
   private void setJarNameProperties(String sProject) throws BuildException
   {
      try
      {
         URL rootURL = XMLMetadataHelper.getURL(URLUtil.toURL(getMetaDir(sProject)), true);
         URL baseURL = null;
         XMLMetadataHelper helper = new XMLMetadataHelper(rootURL, null, null, null);
         Element descriptorElement = helper.getDescriptorElement(true);
         String sRevision = descriptorElement.getAttribute(REVISION_ATTR);
         String sVersion = descriptorElement.getAttribute(VERSION_ATTR);
         String sBaseJarName = null;

         if (!descriptorElement.hasAttribute(BASE_NAMESPACE_ATTR) || sProject.equals(".tmp"))
         {
            if (m_sBaseJarProperty != null)
            {
               getProject().setProperty(m_sBaseJarProperty, "");
            }

            if (m_sBaseProjectProperty != null)
            {
               getProject().setProperty(m_sBaseProjectProperty, "");
            }
           
            if (m_sBasePathProperty != null)
            {
               getProject().setProperty(m_sBasePathProperty, "");
            }
         }
         else
         {
            //Parse the namespace URL to retrieve the base project name.
            String sBaseNamespace = descriptorElement.getAttribute(BASE_NAMESPACE_ATTR);
            String sBaseProject = sBaseNamespace.substring(sBaseNamespace.lastIndexOf('/') + 1);
            String sBaseVersion = descriptorElement.getAttribute(BASE_VERSION_ATTR);
            String sBaseChecksum = descriptorElement.getAttribute(BASE_CHECKSUM_ATTR);
            long lSearchTime, lStartTime = 0;

            if (m_bProfileEnabled)
            {
               lStartTime = System.currentTimeMillis();
            }

            log("Searching for base repository '" + sBaseProject + "' with checksum " + sBaseChecksum);
            sBaseJarName = getPublishedJARName(sBaseProject, sBaseChecksum);

            if (m_bProfileEnabled)
            {
               lSearchTime = System.currentTimeMillis() - lStartTime;
               log("   Search complete (" + lSearchTime + " ms).");
            }

            if (sBaseJarName == null)
            {
               throw new BuildException("Missing base repository '" + sBaseProject + "' with version " +
                  sBaseVersion + " and checksum " + sBaseChecksum);
            }

            if (m_sBaseJarProperty != null)
            {
               getProject().setProperty(m_sBaseJarProperty, sBaseJarName);
            }

            if (m_sBaseProjectProperty != null)
            {
               getProject().setProperty(m_sBaseProjectProperty, sBaseProject);
            }
           
            String sBaseRepositoryPath = XMLMetadataHelper.getRepositoryPath(sBaseNamespace);

            if (m_sBasePathProperty != null)
            {
               getProject().setProperty(m_sBasePathProperty, sBaseRepositoryPath);
            }

            baseURL = getMetaFolderURL(sBaseJarName, sBaseRepositoryPath);
         }

         String sChecksum = null;
        
         try
         {
            helper = new XMLMetadataHelper(rootURL, baseURL, null, null);
           
            sChecksum = helper.getChecksum(true);
         }
         catch (MetadataException e)
         {
            if (baseURL != null)
            {
               // base may be old-style repository, rooted at /nexj/meta
               if (m_sBasePathProperty != null)
               {
                  getProject().setProperty(m_sBasePathProperty, "nexj/meta");
               }

               baseURL = getMetaFolderURL(sBaseJarName, "nexj/meta/");
               helper = new XMLMetadataHelper(rootURL, baseURL, null, null);
              
               sChecksum = helper.getChecksum(true);
            }
            else
            {
               throw e;
            }
         }

         // mixin JARs
         if (m_sMixinJarsProperty != null)
         {
            if (getProject().getProperty(m_sMixinJarsProperty) == null)
            {
               final StringBuffer mixinJarsBuffer = new StringBuffer();

               XMLMetadataHelper.forEachReferencedMixin(descriptorElement, baseURL, new MixinNamespaceHandler()
               {
                  public URL handle(String sNamespace, String sVersion, String sChecksum)
                  {
                     String sMixinProject = sNamespace.substring(sNamespace.lastIndexOf('/') + 1);

                     log("Searching for mixin repository '" + sMixinProject + "' with checksum " + sChecksum);

                     String sMixinJAR = getPublishedJARName(sMixinProject, sChecksum);

                     if (sMixinJAR == null)
                     {
                        throw new BuildException("Missing mixin repository '" + sMixinProject + "' with version " +
                           sVersion + " and checksum " + sChecksum);
                     }

                     if (mixinJarsBuffer.length() > 0)
                     {
                        mixinJarsBuffer.append(File.pathSeparator);
                     }

                     mixinJarsBuffer.append(sMixinJAR);

                     try
                     {
                        URL metaFolderURL = getMetaFolderURL(sMixinJAR, XMLMetadataHelper.getRepositoryPath(sNamespace));

                        getProject().setProperty(SysUtil.PROPERTY_PREFIX + XMLMetadataHelper.getRepositoryProperty(sNamespace), metaFolderURL.toString());

                        return metaFolderURL;
                     }
                     catch (IOException ioe)
                     {
                        throw new BuildException("Unable to resolve metadata folder URL for mixin repository'" + sMixinProject + "' with version " +
                           sVersion + " and checksum " + sChecksum, ioe);
                     }
                  }
               });

               getProject().setProperty(m_sMixinJarsProperty, mixinJarsBuffer.toString());
            }
            else
            {
               log("Mixin property '" + m_sMixinJarsProperty + "' already set. Ignoring.", Project.MSG_DEBUG);
            }
         }

         log("Project '" + sProject + "': revision = " + sRevision + ", version = " + sVersion + ", checksum = " + sChecksum);

         if (getProject().getProperty(m_sMetaJarProperty) == null)
         {
            getProject().setProperty(m_sMetaJarProperty, getJarName(sProject, sRevision, sVersion, sChecksum));
         }
           
         if (m_sChecksumProperty != null)
         {
            getProject().setProperty(m_sChecksumProperty, sChecksum);
         }

         if (m_sVersionProperty != null)
         {
            getProject().setProperty(m_sVersionProperty, sVersion);
         }

         if (m_sRevisionProperty != null)
         {
            getProject().setProperty(m_sRevisionProperty, sRevision);
         }
        
         if (m_sMetaPathProperty != null)
         {
            getProject().setProperty(m_sMetaPathProperty, XMLMetadataHelper.getRepositoryPath(descriptorElement.getAttribute(NAMESPACE_ATTR)));
         }
      }
      catch (IOException e)
      {
         throw new BuildException("Cannot get URL for project " + sProject, e);
      }
   }

   /**
    * Check if all the mandatory Ant Task attributes are set.
    */
   private void checkAttributes()
   {
      if (m_sSrcDir == null)
      {
         throw new BuildException("Undefined srcdir attribute of " + getTaskName());
      }

      if (m_sProject == null)
      {
         throw new BuildException("Undefined project attribute of " + getTaskName());
      }

      if (m_sMetaJarProperty == null)
      {
         throw new BuildException("Undefined metajarproperty attribute of " + getTaskName());
      }

      if (m_sBaseDir == null)
      {
         // default to the publish directory.
         m_sBaseDir = m_sOutDir;
      }
   }

   /**
    * Returns the metadata URL for a given JAR file with repository path.
    *
    * @param sJarFile the path string for the JAR file.
    * @param sRepositoryPath the metadata path within the JAR file.
    * @return a meta URL for a published jar.
    * @throws IOException if a problem is encountered creating the URL object.
    */
   public static URL getMetaFolderURL(String sJarFile, String sRepositoryPath) throws IOException
   {
      StringBuffer sb = new StringBuffer("jar:file:");

      sb.append(sJarFile);
      sb.append("!/" + sRepositoryPath);

      return XMLMetadataHelper.getURL(URLUtil.toURL(sb.toString()), true);
   }

   /**
    * Entry point for Ant Task.
    * Get Jar file names and set them in Ant properties.
    */
   public void execute() throws BuildException
   {
      checkAttributes();
      setJarNameProperties(m_sProject);
   }
}
TOP

Related Classes of nexj.core.build.ProjectJarName

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.