All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cristalise.kernel.collection.Dependency Maven / Gradle / Ivy

Go to download

Cristal-ise is a description-driven software platform originally developed to track the construction of the CMS ECAL detector of the LHC at CERN. This is its core library, known as the kernel, which manages business objects called Items. Items are entirely configured from data, called descriptions, held in other Items. Every change of a state in an Item is a consequence of an execution of an activity in that Item's lifecycle, meaning that Cristal-ise applications are completely traceable, even in their design. It also supports extensive versioning of Item description data, giving the system a high level of flexibility.

There is a newer version: 6.0.0
Show newest version
/**
 * This file is part of the CRISTAL-iSE kernel.
 * Copyright (c) 2001-2015 The CRISTAL Consortium. All rights reserved.
 *
 * 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 3 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; with out 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.
 *
 * http://www.fsf.org/licensing/licenses/lgpl.html
 */
package org.cristalise.kernel.collection;

import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.ACTIVITY_DEF_URN;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.QUERY_NAME;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.QUERY_VERSION;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.SCHEMA_NAME;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.SCHEMA_VERSION;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.SCRIPT_NAME;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.SCRIPT_VERSION;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.STATE_MACHINE_NAME;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.STATE_MACHINE_VERSION;
import static org.cristalise.kernel.graph.model.BuiltInVertexProperties.VERSION;
import static org.cristalise.kernel.property.BuiltInItemProperties.QUERY_URN;
import static org.cristalise.kernel.property.BuiltInItemProperties.SCHEMA_URN;
import static org.cristalise.kernel.property.BuiltInItemProperties.SCRIPT_URN;
import static org.cristalise.kernel.property.BuiltInItemProperties.STATE_MACHINE_URN;
import static org.cristalise.kernel.property.BuiltInItemProperties.WORKFLOW_URN;

import java.util.ArrayList;
import java.util.List;

import org.cristalise.kernel.common.InvalidCollectionModification;
import org.cristalise.kernel.common.InvalidDataException;
import org.cristalise.kernel.common.ObjectAlreadyExistsException;
import org.cristalise.kernel.common.ObjectNotFoundException;
import org.cristalise.kernel.lifecycle.ActivityDef;
import org.cristalise.kernel.lookup.ItemPath;
import org.cristalise.kernel.process.Gateway;
import org.cristalise.kernel.property.Property;
import org.cristalise.kernel.property.PropertyArrayList;
import org.cristalise.kernel.utils.CastorHashMap;
import org.cristalise.kernel.utils.KeyValuePair;
import org.cristalise.kernel.utils.LocalObjectLoader;
import org.cristalise.kernel.utils.Logger;

/**
 * A Collection implementation that contains a variable number of members of the
 * same type, like a variable-length array. CollectionMembers are created and 
 * destroyed as needed. A Dependency never contains empty slots, nor duplicated
 * members.
 * 
 * 

ClassProps are stored at the collection level and duplicated in each slot. * Slots may still have their own individual properties annotating their link. */ public class Dependency extends Collection { protected CastorHashMap mProperties = new CastorHashMap(); protected String mClassProps = ""; public Dependency() { setName("Dependency"); } public Dependency(String name) { setName(name); } public Dependency(String name, Integer version) { setName(name); setVersion(version); } public Dependency(BuiltInCollections collection) { this(collection.getName()); } public Dependency(BuiltInCollections collection, Integer version) { this(collection.getName(), version); } public CastorHashMap getProperties() { return mProperties; } public void setProperties(CastorHashMap props) { mProperties = props; } public KeyValuePair[] getKeyValuePairs() { return mProperties.getKeyValuePairs(); } public void setKeyValuePairs(KeyValuePair[] pairs) { mProperties.setKeyValuePairs(pairs); } public void setClassProps(String classProps) { this.mClassProps = classProps; } public String getClassProps() { return mClassProps; } /** * @return array of Property instances fully initialised from classProps (comma separated values) */ public Property[] getClassProperties() { String[] classPropNames = getClassProps().split(","); Property[] props = new Property[classPropNames.length]; int i = 0; for (String propName: classPropNames) { props[i++] = new Property(propName, (String)getProperties().get(propName)); } return props; } /** * * @param childPath * @param memberNewProps * @throws ObjectNotFoundException * @throws InvalidDataException * @throws InvalidCollectionModification */ public void updateMember(ItemPath childPath, CastorHashMap memberNewProps) throws ObjectNotFoundException, InvalidDataException, InvalidCollectionModification { updateMember(childPath, -1, memberNewProps); } /** * * @param childPath * @param memberID * @param memberNewProps * @throws ObjectNotFoundException * @throws InvalidDataException * @throws InvalidCollectionModification */ public void updateMember(ItemPath childPath, int memberID, CastorHashMap memberNewProps) throws ObjectNotFoundException, InvalidDataException, InvalidCollectionModification { List members = resolveMembers(memberID, childPath); if (members.size() != 1) throw new InvalidDataException("Child item '"+childPath+"' apperars more them once in collection " + mName); DependencyMember member = (DependencyMember) members.get(0); member.updateProperties(memberNewProps); } /** * Add a member to the Dependency * * @param itemPath the Item to be added as a Member * @return DependencyMember the newly created DependencyMember * @throws InvalidCollectionModification if Item is null or the Properties of the Item (e.g. Type) does not match the Collection's * @throws ObjectAlreadyExistsException Item is already a member */ public DependencyMember addMember(ItemPath itemPath) throws InvalidCollectionModification, ObjectAlreadyExistsException { if (itemPath == null) throw new InvalidCollectionModification("Cannot add empty slot to Dependency collection"); if (contains(itemPath)) throw new ObjectAlreadyExistsException("Item "+itemPath+" already exists in Dependency "+getName()); // create member object DependencyMember depMember = new DependencyMember(); depMember.setID(getCounter()); depMember.setProperties((CastorHashMap)mProperties.clone()); depMember.setClassProps(mClassProps); // assign entity depMember.assignItem(itemPath); mMembers.list.add(depMember); Logger.msg(8, "Dependency.addMember(" + itemPath + ") added to children with slotId:"+depMember.getID()); return depMember; } /** * Returns all DependencyMember that are members of the other collection but not members of this one. * * @param other - The collection to compare * @return List of Members */ public List compare(Dependency other) { ArrayList newMembers = new ArrayList(); for (DependencyMember thisMember : other.getMembers().list) { if (!contains(thisMember.getItemPath())) { newMembers.add(thisMember); } } return newMembers; } /** * */ @Override public DependencyMember addMember(ItemPath itemPath, CastorHashMap props, String classProps) throws InvalidCollectionModification, ObjectAlreadyExistsException { if (itemPath == null) throw new InvalidCollectionModification("Cannot add empty slot to Dependency collection"); boolean checkUniqueness = Gateway.getProperties().getBoolean("Dependency.checkMemberUniqueness", true); if (checkUniqueness && contains(itemPath)) throw new ObjectAlreadyExistsException("Item "+itemPath+" already exists in Dependency "+getName()); for (String classProp: mClassProps.split(",")) { if (props.containsKey(classProp)) throw new InvalidCollectionModification("Dependency cannot change classProperties:"+mClassProps); } DependencyMember depMember = new DependencyMember(); depMember.setID(getCounter()); // class props needs to be added for (String classProp: mClassProps.split(",")) props.put(classProp, mProperties.get(classProp)); depMember.setProperties(props); depMember.setClassProps(mClassProps); // assign entity depMember.assignItem(itemPath); mMembers.list.add(depMember); Logger.msg(8, "Dependency.addMember(" + itemPath + ") added to children with slotId:"+depMember.getID()); return depMember; } /** * */ @Override public void removeMember(int memberId) throws ObjectNotFoundException { for (DependencyMember element : mMembers.list) { if (element.getID() == memberId) { mMembers.list.remove(element); return; } } throw new ObjectNotFoundException("Collection name:"+getName()+" does not contains Member id:"+memberId); } /** * Add Dependency specific values to ItemProperties. First checks if there is a Script to be executed, * if no Script defined it will use the default conversion implemented for BuiltInCollections * * @param props the current list of ItemProperties */ public void addToItemProperties(PropertyArrayList props) throws InvalidDataException, ObjectNotFoundException { Logger.msg(2, "Dependency.addToItemProperties("+getName()+") - Starting ..."); //convert to BuiltInCollections BuiltInCollections builtInColl = BuiltInCollections.getValue(getName()); for (DependencyMember member : getMembers().list) { String memberUUID = member.getChildUUID(); Integer memberVer = LocalObjectLoader.deriveVersionNumber(member.getBuiltInProperty(VERSION)); if (memberVer == null) { throw new InvalidDataException("Version is null for Collection:" + getName() + ", MemberUUID:" + memberUUID); } //Do not process this member further // - if Script has done the job already // - or this is not a BuiltInCollection if (convertToItemPropertyByScript(props, member) || builtInColl == null) continue; Logger.msg(5, "Dependency.addToItemProperties() - BuiltIn Dependency:"+getName()+" memberUUID:"+memberUUID); //LocalObjectLoader checks if data is valid and loads object to cache switch (builtInColl) { //*************************************************************************************************** case SCHEMA: LocalObjectLoader.getSchema(memberUUID, memberVer); props.put(new Property(SCHEMA_URN, memberUUID+":"+memberVer)); break; //*************************************************************************************************** case SCRIPT: LocalObjectLoader.getScript(memberUUID, memberVer); props.put(new Property(SCRIPT_URN, memberUUID+":"+memberVer)); break; //*************************************************************************************************** case QUERY: LocalObjectLoader.getQuery(memberUUID, memberVer); props.put(new Property(QUERY_URN, memberUUID+":"+memberVer)); break; //*************************************************************************************************** case STATE_MACHINE: if (Gateway.getProperties().getBoolean("Dependency.addStateMachineURN", false) ) { LocalObjectLoader.getStateMachine(memberUUID, memberVer); props.put(new Property(STATE_MACHINE_URN, memberUUID+":"+memberVer)); } break; //*************************************************************************************************** case WORKFLOW: if (Gateway.getProperties().getBoolean("Dependency.addWorkflowURN", false) ) { LocalObjectLoader.getCompActDef(memberUUID, memberVer); props.put(new Property(WORKFLOW_URN, memberUUID+":"+memberVer)); } break; //*************************************************************************************************** default: Logger.msg(8, "Dependency.addToItemProperties() - Cannot handle BuiltIn Dependency:"+getName()); break; } } } /** * Executes Script if it was defined in the Member properties * * @param props the current list of ItemProperties * @param member the current DependencyMember * @return true when Script was executed * @throws InvalidDataException * @throws ObjectNotFoundException */ private boolean convertToItemPropertyByScript(PropertyArrayList props, DependencyMember member) throws InvalidDataException, ObjectNotFoundException { Logger.msg(5, "Dependency.convertToItemPropertyByScript() - Dependency:"+getName()+" memberUUID:"+member.getChildUUID()); String scriptName = (String)member.getBuiltInProperty(SCRIPT_NAME); if (scriptName != null && scriptName.length() > 0) { PropertyArrayList newProps = (PropertyArrayList)member.evaluateScript(); props.merge(newProps); return true; } return false; } /** * Add Dependency specific values to VertexProperties (CastorHashMap). First checks if there is a Script * to be executed, if no Script defined it will use the default conversion implemented for BuiltInCollections * * @param props the current list of VertexProperties * @throws InvalidDataException inconsistent data was provided * @throws ObjectNotFoundException objects were not found while reading the properties */ public void addToVertexProperties(CastorHashMap props) throws InvalidDataException, ObjectNotFoundException { Logger.msg(2, "Dependency.addToVertexProperties("+getName()+") - Starting ..."); BuiltInCollections builtInColl = BuiltInCollections.getValue(getName()); for (DependencyMember member : getMembers().list) { String memberUUID = member.getChildUUID(); Integer memberVer = LocalObjectLoader.deriveVersionNumber(member.getBuiltInProperty(VERSION)); if (memberVer == null) { throw new InvalidDataException("Version is null for Collection:" + getName() + ", DependencyMember:" + memberUUID); } //Do not process this member further // - if Script has done the job already // - or this is not a BuiltInCollection if (convertToVertextPropsByScript(props, member) || builtInColl == null) continue; Logger.msg(5, "Dependency.addToVertexProperties() - Dependency:"+getName()+" memberUUID:"+memberUUID); //LocalObjectLoader checks if data is valid and loads object to cache switch (builtInColl) { //*************************************************************************************************** case SCHEMA: try { LocalObjectLoader.getSchema(memberUUID, memberVer); props.setBuiltInProperty(SCHEMA_NAME, memberUUID); props.setBuiltInProperty(SCHEMA_VERSION, memberVer); } catch (ObjectNotFoundException e) { //Schema dependency could be defined in Properties if(props.containsKey(SCHEMA_NAME)) { Logger.msg(8, "Dependency.addToVertexProperties() - BACKWARD COMPABILITY: Dependency '"+getName()+"' is defined in Properties"); String uuid = LocalObjectLoader.getSchema(props).getItemPath().getUUID().toString(); props.setBuiltInProperty(SCHEMA_NAME, uuid); } } break; //*************************************************************************************************** case SCRIPT: try { LocalObjectLoader.getScript(memberUUID, memberVer); props.setBuiltInProperty(SCRIPT_NAME, memberUUID); props.setBuiltInProperty(SCRIPT_VERSION, memberVer); } catch (ObjectNotFoundException e) { //Backward compability: Script dependency could be defined in Properties if(props.containsKey(SCRIPT_NAME)) { Logger.msg(8, "Dependency.addToVertexProperties() - BACKWARD COMPABILITY: Dependency '"+getName()+"' is defined in Properties"); String uuid = LocalObjectLoader.getScript(props).getItemPath().getUUID().toString(); props.setBuiltInProperty(SCRIPT_NAME, uuid); } } break; //*************************************************************************************************** case QUERY: try { LocalObjectLoader.getQuery(memberUUID, memberVer); props.setBuiltInProperty(QUERY_NAME, memberUUID); props.setBuiltInProperty(QUERY_VERSION, memberVer); } catch (ObjectNotFoundException e) { //Backward compability: Query dependency could be defined in Properties if(props.containsKey(QUERY_NAME)) { Logger.msg(8, "Dependency.addToVertexProperties() - BACKWARD COMPABILITY: Dependency '"+getName()+"' is defined in Properties"); String uuid = LocalObjectLoader.getQuery(props).getItemPath().getUUID().toString(); props.setBuiltInProperty(QUERY_NAME, uuid); } } break; //*************************************************************************************************** case STATE_MACHINE: try { LocalObjectLoader.getStateMachine(memberUUID, memberVer); props.setBuiltInProperty(STATE_MACHINE_NAME, memberUUID); props.setBuiltInProperty(STATE_MACHINE_VERSION, memberVer); } catch (ObjectNotFoundException e) { if(props.containsKey(STATE_MACHINE_NAME)) { Logger.msg(8, "Dependency.addToVertexProperties() - BACKWARD COMPABILITY: Dependency '"+getName()+"' is defined in Properties"); String uuid = LocalObjectLoader.getStateMachine(props).getItemPath().getUUID().toString(); props.setBuiltInProperty(STATE_MACHINE_NAME, uuid); } } break; //*************************************************************************************************** case ACTIVITY: ActivityDef actDef = LocalObjectLoader.getActDef(memberUUID, memberVer); CastorHashMap chm = null; if(props.containsKey(ACTIVITY_DEF_URN)) { chm = (CastorHashMap)props.getBuiltInProperty(ACTIVITY_DEF_URN); } else { chm = new CastorHashMap(); props.setBuiltInProperty(ACTIVITY_DEF_URN, chm); } Logger.msg(8, "Dependency.addToVertexProperties("+getName()+") - actDef:"+actDef.getActName()); chm.put(actDef.getActName(), memberUUID+"~"+memberVer); break; //*************************************************************************************************** default: Logger.msg(8, "Dependency.addToVertexProperties() - Cannot handle BuiltIn Dependency:"+getName()); break; } } } /** * Executes Script if it was defined in the Member properties * * @param props the current list of VertexProperties * @param member the current DependencyMember * @return true when Script was executed * @throws InvalidDataException * @throws ObjectNotFoundException */ private boolean convertToVertextPropsByScript(CastorHashMap props, DependencyMember member) throws InvalidDataException, ObjectNotFoundException { Logger.msg(5, "Dependency.convertToVertextPropsByScript() - Dependency:"+getName()+" memberUUID:"+member.getChildUUID()); String scriptName = (String)member.getBuiltInProperty(SCRIPT_NAME); if (scriptName != null && scriptName.length() > 0) { CastorHashMap newProps = (CastorHashMap)member.evaluateScript(); props.merge(newProps); return true; } return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy