/** * This file is part of the CRISTAL-iSE kernel. * Copyright (c) 2001-2014 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 com.c2kernel.lifecycle.instance.predefined.item; import com.c2kernel.collection.Collection; import com.c2kernel.collection.CollectionArrayList; import com.c2kernel.collection.CollectionDescription; import com.c2kernel.collection.CollectionMember; import com.c2kernel.common.CannotManage; import com.c2kernel.common.InvalidData; import com.c2kernel.common.ObjectAlreadyExists; import com.c2kernel.common.ObjectCannotBeUpdated; import com.c2kernel.common.ObjectNotFound; import com.c2kernel.common.PersistencyException; import com.c2kernel.entity.CorbaServer; import com.c2kernel.entity.TraceableEntity; import com.c2kernel.lifecycle.CompositeActivityDef; import com.c2kernel.lifecycle.instance.CompositeActivity; import com.c2kernel.lifecycle.instance.predefined.PredefinedStep; import com.c2kernel.lookup.AgentPath; import com.c2kernel.lookup.DomainPath; import com.c2kernel.lookup.ItemPath; import com.c2kernel.persistency.ClusterStorage; import com.c2kernel.process.Gateway; import com.c2kernel.property.Property; import com.c2kernel.property.PropertyArrayList; import com.c2kernel.property.PropertyDescriptionList; import com.c2kernel.property.PropertyUtility; import com.c2kernel.utils.LocalObjectLoader; import com.c2kernel.utils.Logger; /************************************************************************** * * @author $Author: abranson $ $Date: 2005/10/13 08:13:58 $ * @version $Revision: 1.47 $ **************************************************************************/ public class CreateItemFromDescription extends PredefinedStep { public CreateItemFromDescription() { super(); } //requestdata is xmlstring @Override protected String runActivityLogic(AgentPath agent, ItemPath itemPath, int transitionID, String requestData) throws InvalidData, ObjectNotFound, ObjectAlreadyExists, CannotManage, ObjectCannotBeUpdated, PersistencyException { String[] input = getDataList(requestData); String newName = input[0]; String domPath = input[1]; String descVer = input.length > 2 ? input[2]:"last"; PropertyArrayList initProps = input.length > 3?getInitProperties(input[3]):new PropertyArrayList(); Logger.msg(1, "CreateItemFromDescription - Starting."); // check if the path is already taken DomainPath context = new DomainPath(new DomainPath(domPath), newName); //Logger.debug(8,"context "+context.getItemPath()+" "+context.getPath()+" "+context.getString()); if (context.exists()) throw new ObjectAlreadyExists("The path " +context+ " exists already."); // get init objects /* ITEM CREATION */ // generate new entity key Logger.msg(6, "CreateItemFromDescription - Requesting new item path"); ItemPath newItemPath = new ItemPath(); // resolve the item factory Logger.msg(6, "CreateItemFromDescription - Resolving item factory"); // create the Item object Logger.msg(3, "CreateItemFromDescription - Creating Item"); CorbaServer factory = Gateway.getCorbaServer(); if (factory == null) throw new CannotManage("This process cannot create new Items"); TraceableEntity newItem = factory.createItem(newItemPath); Gateway.getLookupManager().add(newItemPath); // initialise it with its properties and workflow Logger.msg(3, "CreateItemFromDescription - Initializing Item"); try { newItem.initialise( agent.getSystemKey(), Gateway.getMarshaller().marshall(getNewProperties(itemPath, descVer, initProps, newName, agent)), Gateway.getMarshaller().marshall(getNewWorkflow(itemPath, descVer)), Gateway.getMarshaller().marshall(getNewCollections(itemPath, descVer)) ); } catch (PersistencyException e) { throw e; } catch (Exception e) { throw new InvalidData("CreateAgentFromDescription: Problem initializing new Agent. See log: "+e.getMessage()); } // add its domain path Logger.msg(3, "CreateItemFromDescription - Creating "+context); context.setItemPath(newItemPath); Gateway.getLookupManager().add(context); return requestData; } protected PropertyArrayList getInitProperties(String input) throws InvalidData { try { return (PropertyArrayList)Gateway.getMarshaller().unmarshall(input); } catch (Exception e) { Logger.error(e); throw new InvalidData("Initial property parameter was not a marshalled PropertyArrayList: "+input); } } protected PropertyArrayList getNewProperties(ItemPath itemPath, String descVer, PropertyArrayList initProps, String newName, AgentPath agent) throws ObjectNotFound, InvalidData { // copy properties -- intend to create from propdesc PropertyDescriptionList pdList = PropertyUtility.getPropertyDescriptionOutcome(itemPath, descVer); PropertyArrayList props = pdList.instantiate(initProps); // set Name prop or create if not present boolean foundName = false; for (Property prop : props.list) { if (prop.getName().equals("Name")) { foundName = true; prop.setValue(newName); } } if (!foundName) props.list.add(new Property("Name", newName, true)); props.list.add( new Property("Creator", agent.getAgentName(), false)); return props; } protected CompositeActivity getNewWorkflow(ItemPath itemPath, String descVer) throws ObjectNotFound, InvalidData, PersistencyException { // find the workflow def for the given description version String wfDefName = null; Integer wfDefVer = null; Collection thisCol = (Collection)Gateway.getStorage().get(itemPath, ClusterStorage.COLLECTION+"/workflow/"+descVer, null); CollectionMember wfMember = thisCol.getMembers().list.get(0); wfDefName = wfMember.resolveItem().getName(); Object wfVerObj = wfMember.getProperties().get("Version"); try { wfDefVer = Integer.parseInt(wfVerObj.toString()); } catch (NumberFormatException ex) { throw new InvalidData("Invalid workflow version number: "+wfVerObj.toString()); } // load workflow def if (wfDefName == null) throw new InvalidData("No workflow given or defined"); if (wfDefVer == null) throw new InvalidData("No workflow def version given"); try { CompositeActivityDef wfDef = (CompositeActivityDef)LocalObjectLoader.getActDef(wfDefName, wfDefVer); return (CompositeActivity)wfDef.instantiate(); } catch (ObjectNotFound ex) { throw new InvalidData("Workflow def '"+wfDefName+"'v"+wfDefVer+" not found"); } catch (ClassCastException ex) { throw new InvalidData("Activity def '"+wfDefName+"' was not Composite"); } } protected CollectionArrayList getNewCollections(ItemPath itemPath, String descVer) throws ObjectNotFound, PersistencyException { // loop through collections, collecting instantiated descriptions and finding the default workflow def CollectionArrayList colls = new CollectionArrayList(); String[] collNames = Gateway.getStorage().getClusterContents(itemPath, ClusterStorage.COLLECTION); for (String collName : collNames) { Collection thisCol = (Collection)Gateway.getStorage().get(itemPath, ClusterStorage.COLLECTION+"/"+collName+"/"+descVer, null); if (thisCol instanceof CollectionDescription) { CollectionDescription thisDesc = (CollectionDescription)thisCol; colls.put(thisDesc.newInstance()); } } return colls; } }