Package org.objectweb.speedo.generation.recompiler

Source Code of org.objectweb.speedo.generation.recompiler.UpToDateVisitor

/**
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.objectweb.speedo.generation.recompiler;

import org.objectweb.speedo.generation.mivisitor.MetaInfoVisitorImpl;
import org.objectweb.speedo.generation.mivisitor.MetaInfoVisitor;
import org.objectweb.speedo.generation.api.SpeedoCompilerParameter;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.mapper.lib.Object2StringSerializer;
import org.objectweb.speedo.tools.StringReplace;
import org.objectweb.speedo.mim.api.PersistentObjectItf;
import org.objectweb.util.monolog.api.BasicLevel;

import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.net.URLClassLoader;
import java.net.URL;
import java.net.MalformedURLException;

/**
* Checks the date of the source and the built files:
* - .jdo / JMI file
* - .java / .class
*
* For each .jdo file, if the .jdo or a .java has been modified all classes
* are removed in order to re-enhance all classed.
*
* TODO: check aware classes
*
* @author S.Chassande-Barrioz
*/
public class UpToDateVisitor extends MetaInfoVisitorImpl {
  private File output;
  private File input;
  private ClassLoader classloader;
  private List xmlsToRemove;
  private List enhancedClasses;

  /**
   * builds a MetaInfoVisitor which is the last of the chain
   */
  public UpToDateVisitor(Personality p) {
    super(p);
  }

  /**
   * builds a MetaInfoVisitor which is the last of the chain
   */
  public UpToDateVisitor(MetaInfoVisitor mim, Personality p) {
    super(mim, p);
  }

  protected String getLoggerName() {
    return super.getLoggerName() + ".uptodate";
  }
    public String getTitle() {
        return "Computing classes requiring enhancement ...";
    }

   
  public boolean init() throws SpeedoException {
    super.init();
    output = new File(scp.output);
    if (!output.exists() && output.mkdirs()) {
      throw new SpeedoException(
          "Impossible to create the output directory: "
          + output.getAbsolutePath());
    }
    input = new File(scp.input);
    if (!input.exists()) {
      throw new SpeedoException("No input directory: "
          + input.getAbsolutePath());
    }
    try {
      classloader = new URLClassLoader(
          new URL[]{new File(scp.output).toURL()},
          getClass().getClassLoader());
    } catch (MalformedURLException e) {

    }
    enhancedClasses = new ArrayList();
    return !scp.getXmldescriptor().isEmpty();
  }

  public void visitCompilerParameter(SpeedoCompilerParameter scp) throws SpeedoException {
    super.visitCompilerParameter(scp);
    if (xmlsToRemove != null) {
      for(int i=(xmlsToRemove.size() -1); i>=0; i--) {
        SpeedoXMLDescriptor xml = (SpeedoXMLDescriptor) xmlsToRemove.get(i);
        scp.getXmldescriptor().remove(xml.xmlFile);
      }
    }
  }

  public void visitXml(SpeedoXMLDescriptor xml) throws SpeedoException {
    //compare the date of the .jdo and JMI files
    File xmlFile = new File(scp.xmlDir, xml.xmlFile);
    File jmiFile = new File(output,
        Object2StringSerializer.descFileName2ClassName(xml.xmlFile)
            + ".class");
    if (debug) {
      logger.log(BasicLevel.DEBUG, "XML file: "
          + xmlFile.getAbsolutePath()
        + "\n\ttime=" + xmlFile.lastModified());
      if (jmiFile.exists()) {
        logger.log(BasicLevel.DEBUG, "JMI file: "
                  + jmiFile.getAbsolutePath()
            + "\n\ttime=" + jmiFile.lastModified());
      } else {
        logger.log(BasicLevel.DEBUG, "NO JMI file found : "
                  + jmiFile.getAbsolutePath());
      }
    }
    xml.requireEnhancement = !jmiFile.exists()
        || (xmlFile.lastModified() > jmiFile.lastModified());
    if (debug) {
      logger.log(BasicLevel.DEBUG, "Enhancement "
          + (xml.requireEnhancement ? "" : "not ")
          + "required for the jdo file:" + xml.xmlFile);
    }
    enhancedClasses.clear();
    super.visitXml(xml);
    List classes = xml.getSpeedoClasses();

    if (!xml.requireEnhancement) {
      for(int i=(classes.size() -1); i>=0 && !xml.requireEnhancement; i--) {
        SpeedoClass sc = (SpeedoClass) classes.get(i);
        sc.setRequireEnhancement(xml.requireEnhancement);
      }
    }
    if (xml.requireEnhancement) {
      logger.log(BasicLevel.INFO, "Enhancement required for :" + xml.xmlFile);

      //Remove the JMI file
      if (debug) {
        logger.log(BasicLevel.DEBUG, "Removing the jmi file:"
            + jmiFile.getAbsolutePath());
      }
      if (jmiFile.exists() && !jmiFile.delete()) {
        throw new SpeedoException(
            "Impossible to remove the JMI file associated to the jdo file:"
            + xml.xmlFile);
      }

      for (int i = (enhancedClasses.size() - 1); i >= 0; i--) {
        SpeedoClass sc = (SpeedoClass) enhancedClasses.get(i);
        String baseName = StringReplace.replaceChar(
            '.', File.separatorChar, sc.getFQName());
        File classFile = new File(output, baseName + ".class");
        if (debug) {
          logger.log(BasicLevel.DEBUG, "Removing class files:" + classFile);
        }
        if (classFile.exists() && !classFile.delete()) {
          throw new SpeedoException("Impossible to remove the file:"
              + classFile.getAbsolutePath());
        }
      }
    } else {
      if (xmlsToRemove == null) {
        xmlsToRemove = new ArrayList();
      }
      xmlsToRemove.add(xml);
    }
    enhancedClasses.clear();//garbage
  }

  public void visitClass(SpeedoClass sc) throws SpeedoException {
    super.visitClass(sc);
    SpeedoXMLDescriptor xml = sc.moPackage.xmlDescriptor;
    sc.setRequireEnhancement(xml.requireEnhancement);
    String baseName = StringReplace.replaceChar(
        '.', File.separatorChar, sc.getFQName());
    File classFile = new File(output, baseName + ".class");
    boolean classExist = classFile.exists();
    if (debug) {
      logger.log(BasicLevel.DEBUG, "Examining the class: " + sc.getFQName());
      if (classExist) {
        logger.log(BasicLevel.DEBUG, "class file: " + classFile.getAbsolutePath());
      }
    }

    boolean javaModified = !classExist;
    if (classExist) {
      //compare the date of the .java and .class files
      File javaFile = new File(scp.input, baseName + ".java");
      logger.log(BasicLevel.DEBUG, "java file: " + javaFile.getAbsolutePath());
      javaModified = (javaFile.lastModified() > classFile.lastModified());

      if (!javaModified) {
        // Is the class already enhanced ?
        try {
          Class clazz = classloader.loadClass(sc.getFQName());
          sc.setAlreadyEnhanced(implement(clazz, PersistentObjectItf.class));
        } catch (NoClassDefFoundError e) {
          logger.log(BasicLevel.DEBUG, "Class " + sc.getFQName(), e);
          javaModified = true; //in order to delete and recompile the class
        } catch (ClassNotFoundException e) {
          logger.log(BasicLevel.DEBUG, "Class " + sc.getFQName(), e);
        } catch (ClassFormatError e) {
          logger.log(BasicLevel.DEBUG, "Class " + sc.getFQName(), e);
        } catch (Throwable e) {
          String msg = "Impossible to analyze the class '" + sc.getFQName() + "': ";
          logger.log(BasicLevel.ERROR, msg, e);
          throw new SpeedoException(msg);
        }
        if (debug) {
          logger.log(BasicLevel.DEBUG, "The class " + sc.getFQName()
              + " is "
              (sc.isAlreadyEnhanced() ? "": "not ")
              + "already enhanced.");
        }
      }
    }
    if (classExist && javaModified) {
      logger.log(BasicLevel.INFO, "The class " + sc.getFQName() + " has been modified (Remove the .class).");
      if (!classFile.delete()) {
          throw new SpeedoException("Impossible to remove the file:"
              + classFile.getAbsolutePath());
      }
    }
    sc.setRequireEnhancement(!classExist || javaModified || !sc.isAlreadyEnhanced());
    if (!sc.requireEnhancement()) {
      enhancedClasses.add(sc);
    }

    //if this class requires the enhancement, the xml too
    xml.requireEnhancement |= sc.requireEnhancement() ;
  }

  private boolean implement(Class clazz, Class itf) {
    boolean res = Arrays.asList(clazz.getInterfaces()).contains(itf);
    if (debug) {
      logger.log(BasicLevel.DEBUG, "The class " + clazz.getName() + " is "
          + (res ? "" : "not ") + "a " + itf.getName());
    }
    return res || (clazz.getSuperclass() != null
            && implement(clazz.getSuperclass(), itf));
  }
}
TOP

Related Classes of org.objectweb.speedo.generation.recompiler.UpToDateVisitor

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.