Package org.objectweb.speedo.mapper.lib

Source Code of org.objectweb.speedo.mapper.lib.ClassPropertiesManager$Prop

/**
* Copyright (C) 2001-2005 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.mapper.lib;

import org.objectweb.jorm.api.PMapper;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.mapper.api.ClassPropertyManager;
import org.objectweb.speedo.mim.api.HomeItf;
import org.objectweb.speedo.tools.StringReplace;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;


public class ClassPropertiesManager implements SpeedoProperties {
 
  public final static char FIELD_SEP = '#';
 
  final Properties speedoProperties;
   
    final HashMap name2prop;

    final HashMap pattern2prop;
   
    /**
     * key = property prefix
     * value = ClassProperty instance
     */
    final HashMap prefix2Impl;

    /**
   * The mapper holding homes of the persistent classes
   */
  protected PMapper mapper = null;
 
  protected Logger logger;
 
  public ClassPropertiesManager() {
    speedoProperties = new Properties();
        name2prop = new HashMap();
    pattern2prop = new HashMap();
    prefix2Impl = new HashMap();
    addClassPropertyManager(new CPMCacheClassPolicy());
    addClassPropertyManager(new CPMShareablePolicy());
    addClassPropertyManager(new CPMTransactionLockingLevel());
    addClassPropertyManager(new CPMUserCachePolicy());
    addClassPropertyManager(new CPMPrefetchOnQuery());
    addClassPropertyManager(new CPMPrefetchOnExtent());
    addClassPropertyManager(new CPMPrefetchOnGenClass());
  }
 
  public void addClassPropertyManager(ClassPropertyManager cpm) {
    prefix2Impl.put(cpm.getName(), cpm);
  }
 
  /**
   * Sets all properties.
   * @param props
   */
    public void addProperties(Properties props) {
        if (props == null || props.size() == 0) {
            return;
        }
        String[] classNames = mapper.getMappedClasses();
        boolean apply = classNames != null && classNames.length > 0;
        for(Iterator it=props.entrySet().iterator(); it.hasNext();) {
            Map.Entry me = (Map.Entry) it.next();
            Prop prop = createProperty(
                (String) me.getKey(), (String) me.getValue());
            if (apply) { // && prop.patternIsRegExp
              applyProperty(prop, classNames);
            }
        }
    }
   
    /**
     * Set a property
     * @param name is the property name
     * @param value is the property value
     */
    public void addProperty(String name, String value) {
        if (value == null || value.length() == 0) {
            removeProperty(name);
        } else {
            Prop prop = createProperty(name, value);
            if (prop.patternIsRegExp) {
                String[] classNames = mapper.getMappedClasses();
                if (classNames != null && classNames.length > 0) {
                  applyProperty(prop, classNames);
                }
            }
        }
    }

    /**
     * Applies current properties to a home of a persistent class.
     * @param sh is the home of the persistent class.
     */
    public void applyProperties(HomeItf sh) {
      if (pattern2prop.size()==0) {
        for (Iterator it = prefix2Impl.values().iterator(); it.hasNext();) {
          ClassPropertyManager cpm = (ClassPropertyManager) it.next();
          cpm.applyDefault(sh, speedoProperties, logger);
      }
          return;
      }
    String path = sh.getPath();
      for (Iterator iter = pattern2prop.values().iterator(); iter.hasNext();) {
      Prop prop = (Prop) iter.next();
      if (prop.match(path)) {
        prop.applyProperty(sh);
      }
    }
    }
    /**
     * Applies current properties to a home of a generic persistent class.
     * @param gcHome is the home of the persistent class.
     */
    public void applyProperties(HomeItf gcHome, HomeItf refHome) {
      if (pattern2prop.size()==0) {
        for (Iterator it = prefix2Impl.values().iterator(); it.hasNext();) {
          ClassPropertyManager cpm = (ClassPropertyManager) it.next();
          cpm.applyDefault(gcHome, refHome, speedoProperties, logger);
      }
          return;
      }
    String path = gcHome.getPath();
      for (Iterator iter = pattern2prop.values().iterator(); iter.hasNext();) {
      Prop prop = (Prop) iter.next();
      if (prop.match(path)) {
        prop.applyProperty(gcHome, refHome);
      }
    }
    }
   
    public Properties getProperties() {
      return speedoProperties;
    }
   
    private synchronized Prop createProperty(String name, String value) {
        if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG, "Set property " + name + "=" + value);
        }
        return new Prop(name, value);
    }

    private synchronized void removeProperty(String name) {
        if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
            logger.log(BasicLevel.DEBUG, "Remove property " + name);
        }
        speedoProperties.remove(name);
        Prop oldProp = (Prop) name2prop.remove(name);
        if (oldProp != null && oldProp.pa != null) {
            pattern2prop.remove(oldProp.pa);
        }
    }
   
  /**
   * Internal representation of a property.
   * A property has a pattern if it follows this profile of
   * expression: xxx(yyy) where xxx is the prefix and yyy is the pattern
   * characterizing class names.
   *
   * @author S.Chassande-Barrioz
   */
  private final class Prop {
    /**
     * The name of the property
     */
    public final String name;
    /**
     * The value of the property
     */
    public final String value;
    public final String prefix;
    public final String pattern;
    public final boolean patternOnField;
    public final boolean patternIsRegExp;
        public final Pattern pa;
        public ClassPropertyManager cpm;
   
    public Prop(String n, String v) {
      this.name = n;
      this.value = v;
        speedoProperties.put(name, value);
            Prop oldProp = (Prop) name2prop.put(name, this);
            if (oldProp != null && oldProp.pa != null) {
                pattern2prop.remove(oldProp.pa);
            }
      int idx1 = name.indexOf('(');
      int idx2 = name.indexOf(')');
      if (idx2 > idx1 && idx1 > 0) {
        this.prefix = name.substring(0, idx1);
        cpm = (ClassPropertyManager) prefix2Impl.get(this.prefix);
        this.pattern = name.substring(idx1 + 1, idx2);
        this.patternIsRegExp = this.pattern != null
          && (this.pattern.indexOf('*') != -1 || this.pattern.indexOf('?') != -1);
        this.patternOnField = pattern.indexOf(FIELD_SEP) > 0;
        if (this.patternIsRegExp) {
          this.pa = Pattern.compile(StringReplace.toJavaPattern(this.pattern));
                pattern2prop.put(pa, this);
        } else {
          this.pa = null;
        }
      } else {
        this.prefix = null;
        this.pattern = null;
        this.patternOnField = false;
        this.patternIsRegExp = false;
        this.pa = null;
        this.cpm = null;
        if (idx1 == -1 && idx2 == -1) {
          //no pattern and no prefix
        } else if (idx1 >= idx2 && logger != null) {
          logger.log(BasicLevel.WARN, "Property '" + name + "' is malformed");
        }
      }
    }
   
    public boolean match(String path) {
      boolean match = patternIsRegExp && pa.matcher(path).matches();
            if (match && logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG, "Property '" + name
                    + "' matches the pattern '" + path
                    + "', value=" + value);
            }
            return match;
    }
      public void applyProperty(HomeItf sh) {
        if (cpm == null) {
          cpm = (ClassPropertyManager) prefix2Impl.get(prefix);
        }
        if (cpm == null) {
          logger.log(BasicLevel.WARN, "Cannot apply the property '"
              + name + "' to '" + sh.getPath() + "': "
                        + "\n\tprefix= " + prefix
                        + "\nprefix2Impl=" + prefix2Impl);
        } else {
          cpm.applyProperty(name, value, sh, speedoProperties, logger);
        }
      }
      public void applyProperty(HomeItf gcHome, HomeItf refHome) {
        if (cpm == null) {
          cpm = (ClassPropertyManager) prefix2Impl.get(prefix);
        }
        if (cpm == null) {
          logger.log(BasicLevel.WARN, "Cannot apply the property '"
              + name + "' to '" + gcHome.getPath() + "'.");
        } else {
          cpm.applyProperty(name, value, gcHome, refHome, speedoProperties, logger);
        }
      }
  }

  /**
   * Applies a property on known persistent classes
   * @param prop is the property to apply
   * @param classNames is the list of known persistent classes
   */
  private void applyProperty(final Prop prop, final String[] classNames) {
      if (prop.pattern != null) {
        return;
      }
      //Iterator over each konwn class to apply property if the pattern match
      for (int i = 0; i < classNames.length; i++) {
        if (prop.patternOnField) {
          //Fetch list of fields belong the class
          HomeItf sh = (HomeItf) mapper.lookup(classNames[i]);
            //TODO: provide in HomeItf (PClassMapping maybe) a new method
          // returning the list of persistent field.
          String[] fieldNames = new String[0]; //sh.get ...
            for (int j = 0; j < fieldNames.length; j++) {
              //build the path from the class name and the field name
              String path = classNames[i] + FIELD_SEP + fieldNames[j];
              if (prop.match(path)) {
                //The path matches
                HomeItf subHome;
                try {
                  //Try to find the home of the gen clas if the field
                  // corresponds to a genclass reference
                  subHome = (HomeItf) sh.getGenClassMapping(fieldNames[i]);
                } catch (UnsupportedOperationException e) {
                  //The field is not a reference to gen class
                  subHome = sh;
                }
                //apply the property on the home
                  prop.applyProperty(subHome);
              }
        }
        } else if (prop.match(classNames[i])) {
          //the property is not for a field and matches to the class name
          String path = classNames[i];
          //find the home corresponding to the class name
             HomeItf sh = (HomeItf) mapper.lookup(path);
        //apply the property on the home
          prop.applyProperty(sh);
        }
    }
    }
}
TOP

Related Classes of org.objectweb.speedo.mapper.lib.ClassPropertiesManager$Prop

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.