SchemaClassResolver.java :  » Web-Framework » roma-webwizard » org » romaframework » core » schema » Java Open Source

Java Open Source » Web Framework » roma webwizard 
roma webwizard » org » romaframework » core » schema » SchemaClassResolver.java
/*
 * Copyright 2006-2007 Luca Garulli (luca.garulli@assetdata.it)
 *
 * Licensed under 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.
 */

package org.romaframework.core.schema;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.romaframework.core.Utility;
import org.romaframework.core.classloader.RomaClassLoader;
import org.romaframework.core.flow.Controller;
import org.romaframework.core.flow.ObjectContext;
import org.romaframework.core.resource.ResourceResolver;
import org.romaframework.core.resource.ResourceResolverListener;

/**
 * Resolve entity class and descriptors using the paths configured.
 * 
 * @author Luca Garulli (luca.garulli@assetdata.it)
 */
public class SchemaClassResolver implements ResourceResolverListener {

  private final Map<String, String> classes                  = new HashMap<String, String>();
  private final Map<String, String> descriptors              = new HashMap<String, String>();
  private final Map<String, File>   resourceFileOwnerMapping = new HashMap<String, File>();

  private List<String>              packages                 = new ArrayList<String>();
  private ResourceResolver          resourceResolver;

  public static final String        DOMAIN_PACKAGE_NAME      = "domain";
  public static final String        CLASS_SUFFIX             = ".class";
  public static final String        DESCRIPTOR_SUFFIX        = ".xml";

  private static Log                log                      = LogFactory.getLog(SchemaClassResolver.class);

  public SchemaClassResolver(ResourceResolver iResourceResolver) {
    resourceResolver = iResourceResolver;
    Controller.getInstance().registerListener(ResourceResolverListener.class, this);
  }

  protected boolean acceptResorce(String iResource) {
    return iResource.endsWith(CLASS_SUFFIX) || iResource.endsWith(DESCRIPTOR_SUFFIX);
  }

  public void addPackage(String iPath) {
    log.debug("[SchemaClassResolver.addPackage] " + iPath);

    packages.add(iPath.replace(File.separatorChar, '.'));
    resourceResolver.loadResources(iPath);
  }

  public void setPackages(List<String> iPackages) {
    for (String i : iPackages) {
      addPackage(i);
    }
  }

  /**
   * Get the Class instance for a requested entity.
   * 
   * @param iEntityName
   *          Entity name to find
   * @return Class instance if found, null otherwise
   */
  public Class<?> getEntityClass(String iEntityName) {
    try {
      String pkg = classes.get(iEntityName);
      if (pkg == null)
        return null;

      return Class.forName(pkg + iEntityName);
    } catch (Throwable t) {
      // NOT FOUND, TRY AGAIN WITH THE NEXT ONE
    }
    return null;
  }

  /**
   * Get the Class instance for a requested entity.
   * 
   * @param iEntityName
   *          Entity name to find
   * @return Class instance if found, null otherwise
   */
  public List<Class<?>> getEntityClassByInheritance(Class<?> iBaseClass) {
    List<Class<?>> result = new ArrayList<Class<?>>();

    Set<String> classNames = classes.keySet();

    for (String className : classNames) {
      try {
        String pkg = classes.get(className);
        if (pkg == null)
          continue;
        Class<?> class1 = Class.forName(pkg + className);
        if (iBaseClass.isAssignableFrom(class1))
          result.add(class1);
      }catch(Throwable t){
        // NOT FOUND, TRY AGAIN WITH THE NEXT ONE          
      }
    }
    return result;
  }
  
  public List<Class<?>> getEntityClassesByPackage(String packageName) {
    List<Class<?>> result = new ArrayList<Class<?>>();
    if(classes==null) return result;
    
    Set<String> classNames = classes.keySet();

    for (String className : classNames) {
      try{
        String pkg = classes.get(className);
        if (pkg == null)
          continue;
        if (pkg.startsWith(packageName)){
          Class<?> class1 = Class.forName(pkg + className);
          result.add(class1);
        }
      }catch(Exception e){
      }
    }
    return result;
  }

  public String getEntityDescriptor(String iEntityName) {
    String path = descriptors.get(iEntityName);
    if (path == null)
      return null;
    return path + iEntityName + DESCRIPTOR_SUFFIX;
  }

  public String[] getClassPackages() {
    return packages.toArray(new String[packages.size()]);
  }

  public void addDomainPackage(String iPath) {
    addPackage(iPath + Utility.PACKAGE_SEPARATOR + DOMAIN_PACKAGE_NAME);
  }

  public void addResource(File iFile, String iName, String iPackagePrefix, String iStartingPackage) {
    if (!iPackagePrefix.startsWith(iStartingPackage))
      return;

    if (iName.toLowerCase().endsWith(CLASS_SUFFIX)) {
      addResourceClass(iFile, iName, iPackagePrefix);
    } else if (iName.toLowerCase().endsWith(DESCRIPTOR_SUFFIX)) {
      addResourceDescriptor(iFile, iName, iPackagePrefix);
    }

    resourceFileOwnerMapping.put(iName, iFile);
  }

  public File getFileOwner(String iResourceName) {
    return resourceFileOwnerMapping.get(iResourceName);
  }

  public Class<?> reloadEntityClass(String iClassName) throws ClassNotFoundException {
    String classPaths[] = ObjectContext.getInstance().getComponent(ResourceResolver.class).getClassPaths();
    URL[] urls = new URL[classPaths.length];
    for (int i = 0; i < classPaths.length; ++i) {
      for (String item : classPaths[i].split(File.pathSeparator)) {
        try {
          urls[i] = new File(item).toURL();
        } catch (MalformedURLException e) {
          log.error("[RomaClassLoader.init] Bad url setting classpath: " + item);
        }
      }
    }

    RomaClassLoader clsLoader = new RomaClassLoader();
    Thread.currentThread().setContextClassLoader(clsLoader);
    Class<?> cls = clsLoader.reloadClass(iClassName);

    return cls;
  }

  private void addResourceClass(File iFile, String iName, String iPackagePrefix) {
    // ADD A NEW CLASS
    String name = iName.substring(0, iName.length() - CLASS_SUFFIX.length());
    String currentPath = classes.get(name);
    if (currentPath != null) {
      // ALREADY EXISTS
      if (currentPath.equals(iPackagePrefix))
        // SAME PATH: PROBABLY DUPLICATE JAR OR JAR+CLASSES REDOUNDANCY
        log.warn("[SchemaClassResolver.addResourceClass] Warning: found the class " + name
            + " defined twice in the classpath and they point to the same package " + iPackagePrefix
            + " Assure you have only one class to avoid alignment problems. Current path is: " + iFile);
      else
        // ALREADY EXISTS
        log.warn("[SchemaClassResolver.addResourceClass] Found the class " + name + " defined twice. Ignore current package "
            + iPackagePrefix + " Use the first one found: " + currentPath + " from path: " + iFile);
    } else {
      if (log.isDebugEnabled())
        log.debug("[SchemaClassResolver.addResourceClass] > Loading class: " + iName + " from path: " + iFile
            + " using the package: " + iPackagePrefix);

      classes.put(name, iPackagePrefix);
    }
  }

  private void addResourceDescriptor(File iFile, String iName, String iPackagePrefix) {
    if (log.isDebugEnabled())
      log.debug("[SchemaClassResolver.addResourceDescriptor] > Loading descriptor: " + iName + " from: " + iPackagePrefix);

    String currentPath = descriptors.get(iName);
    String name = iName.substring(0, iName.length() - DESCRIPTOR_SUFFIX.length());

    if (currentPath != null) {
      // ALREADY EXISTS
      if (currentPath.equals(iPackagePrefix))
        // ALREADY EXISTS
        log.warn("[SchemaClassResolver.addResourceDescriptor] Warning: found the Xml Annotation " + name
            + " defined twice in the classpath and they point to the same package " + iPackagePrefix
            + " Assure you have only one class to avoid alignment problems. Current path is: " + iFile);
      else
        // ALREADY EXISTS
        log.warn("[SchemaClassResolver.addResourceDescriptor] Found the Xml Annotation " + name
            + " defined twice. Ignore current package " + iPackagePrefix + " Use the first one found: " + currentPath
            + " from path: " + iFile);
    } else {
      if (log.isDebugEnabled())
        log.debug("[SchemaClassResolver.addResourceDescriptor] > Loading Xml Annotation: " + iName + " from path: " + iFile
            + " using the package: " + iPackagePrefix);

      descriptors.put(name, Utility.PATH_SEPARATOR + iPackagePrefix.replace('.', Utility.PATH_SEPARATOR));
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.