Package org.chromattic.core

Source Code of org.chromattic.core.PersistentContextState

/*
* Copyright (C) 2003-2009 eXo Platform SAS.
*
* This 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.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.chromattic.core;

import org.chromattic.api.Status;
import org.chromattic.api.UndeclaredRepositoryException;
import org.chromattic.api.NoSuchPropertyException;
import org.chromattic.core.bean.SimpleValueInfo;
import org.chromattic.core.bean.SimpleType;
import org.chromattic.core.mapper.ValueMapper;
import org.chromattic.core.mapper.TypeMapper;
import org.chromattic.common.JCR;
import org.chromattic.common.CloneableInputStream;
import org.chromattic.common.CopyingInputStream;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.Property;
import javax.jcr.ValueFactory;
import javax.jcr.PropertyType;
import javax.jcr.nodetype.PropertyDefinition;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Date;
import java.lang.reflect.Array;
import java.io.InputStream;
import java.io.IOException;

/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
class PersistentContextState extends ContextState {

  /** . */
  private final TypeMapper mapper;

  /** . */
  private final String name;

  /** . */
  private final String path;

  /** . */
  private final String id;

  /** . */
  private final Node node;

  /** . */
  private final DomainSession session;

  /** . */
  private final Map<String, Object> propertyCache;

  PersistentContextState(TypeMapper mapper, Node node, DomainSession session) throws RepositoryException {
    super(node.getPrimaryNodeType());

    //
    this.mapper = mapper;
    this.id = node.getUUID();
    this.path = node.getPath();
    this.node = node;
    this.name = node.getName();
    this.session = session;
    this.propertyCache = session.domain.stateCacheEnabled ? new HashMap<String, Object>() : null;
  }

  String getId() {
    return id;
  }

  String getPath() {
    return path;
  }

  String getName() {
    return name;
  }

  void setName(String name) {
    throw new IllegalStateException("Node name are read only");
  }

  Node getNode() {
    return node;
  }

  DomainSession getSession() {
    return session;
  }

  Status getStatus() {
    return Status.PERSISTENT;
  }

  Object getPropertyValue(String propertyName, SimpleValueInfo type) {
    try {
      Object value = null;

      //
      if (propertyCache != null) {
        value = propertyCache.get(propertyName);
      }

      //
      if (value == null) {
        Value jcrValue;
        if (node.hasProperty(propertyName)) {
          Property property = node.getProperty(propertyName);
          PropertyDefinition def = property.getDefinition();
          if (def.isMultiple()) {
            Value[] values = property.getValues();
            if (values.length == 0) {
              jcrValue = null;
            } else {
              jcrValue = values[0];
            }
          } else {
            jcrValue = property.getValue();
          }
        } else {
          jcrValue = null;
        }

        //
        if (jcrValue != null) {
          SimpleType st = type != null ? type.getSimpleType() : null;
          value = ValueMapper.instance.get(jcrValue, st);

          //
          if (propertyCache != null) {
            if (value instanceof InputStream) {
              try {
                value = new CloneableInputStream((InputStream)value);
              }
              catch (IOException e) {
                throw new AssertionError(e);
              }
            }
          }
        }
      }

      //
      if (value == null) {
        if (type != null && type.isPrimitive()) {
          throw new IllegalStateException("Cannot convert null to primitive type " + type.getSimpleType());
        }
      } else {
        if (propertyCache != null) {
          if (value instanceof InputStream) {
            value = ((CloneableInputStream)value).clone();
          } else if (value instanceof Date) {
            value = ((Date)value).clone();
          }
        }
      }

      //
      return value;
    }
    catch (RepositoryException e) {
      throw new UndeclaredRepositoryException(e);
    }
  }

  <T> T getPropertyValues(String propertyName, SimpleValueInfo simpleType, ListType<T> listType) {
    try {
      Value[] values;
      if (node.hasProperty(propertyName)) {
        Property property = node.getProperty(propertyName);
        PropertyDefinition def = property.getDefinition();
        if (def.isMultiple()) {
          values = property.getValues();
        } else {
          values = new Value[]{property.getValue()};
        }
      } else {
        values = new Value[0];
      }

      //
      if (listType == ListType.LIST) {
        List<Object> list = new ArrayList<Object>(values.length);
        for (Value value : values) {
          Object o = ValueMapper.instance.get(value, simpleType.getSimpleType());
          list.add(o);
        }
        return (T)list;
      } else {
        Object array = Array.newInstance((Class<?>)simpleType.getTypeInfo().getType(), values.length);
        for (int i = 0;i < values.length;i++) {
          Value value = values[i];
          Object o = ValueMapper.instance.get(value, simpleType.getSimpleType());
          Array.set(array, i, o);
        }
        return (T)array;
      }
    }
    catch (RepositoryException e) {
      throw new UndeclaredRepositoryException(e);
    }
  }

  void setPropertyValue(String propertyName, SimpleValueInfo type, Object propertyValue) {
    try {
      if (propertyCache != null) {
        if (propertyValue instanceof InputStream) {
          propertyValue = new CopyingInputStream((InputStream)propertyValue);
        }
      }

      //
      Value jcrValue;
      if (propertyValue != null) {
        ValueFactory valueFactory = session.getJCRSession().getValueFactory();
        SimpleType st = type != null ? type.getSimpleType() : null;
        jcrValue = ValueMapper.instance.get(valueFactory, propertyValue, st);
      } else {
        jcrValue = null;
      }

      //
      PropertyDefinition def = JCR.findPropertyDefinition(node, propertyName);

      //
      if (def == null) {
        throw new NoSuchPropertyException("Property " + propertyName + " cannot be set on node " + node.getPath() + "  with type " + node.getPrimaryNodeType().getName());
      }

      //
      if (jcrValue != null) {
        int neededType = def.getRequiredType();
        if (neededType != PropertyType.UNDEFINED) {
          if (neededType != jcrValue.getType()) {
            throw new ClassCastException("Cannot cast type " + jcrValue.getType() + " to type " + neededType + " when setting property " + propertyName);
          }
        }
      }

      //
      if (def.isMultiple()) {
        if (jcrValue == null) {
          node.setProperty(propertyName, new Value[0]);
        } else {
          node.setProperty(propertyName, new Value[]{jcrValue});
        }
      } else {
        node.setProperty(propertyName, jcrValue);
      }

      //
      if (propertyCache != null) {
        if (propertyValue != null) {
          if (propertyValue instanceof InputStream) {
            byte[] bytes = ((CopyingInputStream)propertyValue).getBytes();
            propertyValue = new CloneableInputStream(bytes);
          } else if (propertyValue instanceof Date) {
            propertyValue = ((Date)propertyValue).clone();
          }
          propertyCache.put(propertyName, propertyValue);
        } else {
          propertyCache.remove(propertyName);
        }
      }
    }
    catch (RepositoryException e) {
      throw new UndeclaredRepositoryException(e);
    }
  }

  <T> void setPropertyValues(String propertyName, SimpleValueInfo type, ListType<T> listType, T objects) {
    if (objects == null) {
      throw new NullPointerException();
    }
    try {
      ValueFactory valueFactory = session.getJCRSession().getValueFactory();
      SimpleType st = type != null ? type.getSimpleType() : null;
      Value[] values;
      if (listType == ListType.LIST) {
        List<?> list = (List<?>)objects;
        values = new Value[list.size()];
        int i = 0;
        for (Object object : list) {
          values[i++] = ValueMapper.instance.get(valueFactory, object, st);
        }
      } else {
        values = new Value[Array.getLength(objects)];
        for (int i = 0;i < values.length;i++) {
          Object o = Array.get(objects, i);
          values[i] = ValueMapper.instance.get(valueFactory, o, st);
        }
      }

      //
      PropertyDefinition def = JCR.getPropertyDefinition(node, propertyName);
      if (def.isMultiple()) {
        node.setProperty(propertyName, values);
      } else {
        if (values.length > 1) {
          throw new IllegalArgumentException("Cannot update with an array of length greater than 1");
        } else if (values.length == 1) {
          node.setProperty(propertyName, values[0]);
        } else {
          node.setProperty(propertyName, (Value)null);
        }
      }
    }
    catch (RepositoryException e) {
      throw new UndeclaredRepositoryException(e);
    }
  }

  public String toString() {
    return "ObjectStatus[id=" + id + ",status=" + Status.PERSISTENT + "]";
  }
}
TOP

Related Classes of org.chromattic.core.PersistentContextState

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.