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

org.cristalise.kernel.collection.Collection 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.VERSION;

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

import org.cristalise.kernel.common.InvalidCollectionModification;
import org.cristalise.kernel.common.ObjectAlreadyExistsException;
import org.cristalise.kernel.common.ObjectNotFoundException;
import org.cristalise.kernel.entity.C2KLocalObject;
import org.cristalise.kernel.graph.model.GraphModel;
import org.cristalise.kernel.lookup.ItemPath;
import org.cristalise.kernel.persistency.ClusterType;
import org.cristalise.kernel.utils.CastorHashMap;

/**
 * Collections are Item local objects that reference other Items.
 * 
 * 

* In parallel with the OO meta-model, Items can be linked to other Items in different ways. These links are modelled with Collections, * which are local objects stored in an Item which reference a number of other Items in the same server. The Collections holds a * CollectionMember, sometimes known as a slot, to reference each Item and store additional information about the link. * *

* Features: *

    *
  • Typing - Collections can restrict membership of based on type information derived from Item, Property and Collection * descriptions. This restriction may be per-slot or apply to the whole Collection. * *
  • Fixed or flexible slots - The CollectionMember objects of a Collection may be empty, individually typed, or created and * removed as required, simulating either array, structures or lists. * *
  • Layout - Collections can include a {@link GraphModel} to lay out its slots on a two-dimensional canvas, for modelling real * world compositions. *
* *

* Collections are managed through predefined steps. */ abstract public class Collection implements C2KLocalObject { private int mCounter = -1; // Contains next available Member ID protected CollectionMemberList mMembers = new CollectionMemberList(); protected String mName = ""; // Not checked for uniqueness protected Integer mVersion = null; /** * Fetch the current highest member ID of the collection. This is found by scanning all the current members * and kept in the mCounter field, but is not persistent. * * @return the current highest member ID */ public int getCounter() { if (mCounter == -1) { for (E element : mMembers.list) { if (mCounter < element.getID()) mCounter = element.getID(); } } return ++mCounter; } /** * @return The total number of slots in this collection, including empty ones */ public int size() { return mMembers.list.size(); } /** * Sets the collection name */ @Override public void setName(String name) { mName = name; } /** * @return The collection's name */ @Override public String getName() { return mName; } /** * Get the collection version. Null if not set, and will be stored as 'last' * * @return Integer version */ public Integer getVersion() { return mVersion; } /** * Set a named version for this collection. Must be an integer or null. Named versions will be stored separately to the current version * ('last') and should not change once saved. * * @param version the version to set */ public void setVersion(Integer version) { this.mVersion = version; } /** * Get the version name for storage, which is 'last' unless the version number is set. * * @return String */ public String getVersionName() { return mVersion == null ? "last" : String.valueOf(mVersion); } @Override public ClusterType getClusterType() { return ClusterType.COLLECTION; } @Override public String getClusterPath() { return getClusterType()+"/"+mName+"/"+getVersionName(); } public void setMembers(CollectionMemberList newMembers) { mMembers = newMembers; } public boolean contains(ItemPath itemPath) { for (E element : mMembers.list) { if (element.getItemPath().equals(itemPath)) return true; } return false; } /** * Gets the description version referenced by the given collection member. Assumes 'last' if version not given. * * @param mem * The member in question * @return String version tag */ public String getDescVer(E mem) { String descVer = "last"; Object descVerObj = mem.getProperties().getBuiltInProperty(VERSION); if (descVerObj != null) descVer = descVerObj.toString(); return descVer; } /** * Check if all slots have an assigned Item * * @return boolean */ public boolean isFull() { for (E element : mMembers.list) { if (element.getItemPath() == null) return false; } return true; } /** * Find collection member by integer ID * * @param memberId * to find * @return the CollectionMember with that ID * @throws ObjectNotFoundException * when the ID wasn't found */ public E getMember(int memberId) throws ObjectNotFoundException { for (E element : mMembers.list) { if (element.getID() == memberId) return element; } throw new ObjectNotFoundException("Member " + memberId + " not found in " + mName); } public CollectionMemberList getMembers() { return mMembers; } /** * Add a member to this collection, with the given property and class properties and optionally an Item to assign, which may be null if * the collection allows empty slots. * * @param itemPath * the Item to assign to the new slot. Optional for collections that allow empty slots * @param props * the Properties of the new member * @param classProps * the names of the properties that dictate the type of assigned Items. * @return the new CollectionMember instance * @throws InvalidCollectionModification * when the assignment was invalid because of collection constraints, such as global type constraints, or not allowing empty * slots. * @throws ObjectAlreadyExistsException * some collections don't allow multiple slots assigned to the same Item, and throw this Exception if it is attempted */ public abstract E addMember(ItemPath itemPath, CastorHashMap props, String classProps) throws InvalidCollectionModification, ObjectAlreadyExistsException; /** * Removes the slot with the given ID from the collection. * * @param memberId * to remove * @throws ObjectNotFoundException * when there was no slot with this ID found. */ public abstract void removeMember(int memberId) throws ObjectNotFoundException; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((mMembers == null) ? 0 : mMembers.hashCode()); result = prime * result + ((mName == null) ? 0 : mName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Collection other = (Collection) obj; if (mMembers == null && other.mMembers != null) return false; else if (!mMembers.equals(other.mMembers)) return false; if (mName == null && other.mName != null) return false; else if (!mName.equals(other.mName)) return false; return true; } /** * Helper method to find all the members for the given item. * * @param childPath the UUID of the item in the slots * @return the list of members found for the given item * @throws ObjectNotFoundException there is not member found for the given input parameters */ public List resolveMembers(ItemPath childPath) throws ObjectNotFoundException { return resolveMembers(-1, childPath); } /** * Helper method to find all the members with the combination of the input parameters. * * @param slotID The id of the slot (aka memberID). When it is set to -1, only the chilPath is used for searching. * @param childPath The UUID of the item in the slots. When it is set to null, only the slotID is used for searching. * @return the list of members found for the combination of the input parameters * @throws ObjectNotFoundException if no member was found for the given input parameters */ public List resolveMembers(int slotID, ItemPath childPath) throws ObjectNotFoundException { ArrayList members = new ArrayList<>(); if (slotID > -1) { // find the member for the given ID E slot = getMember(slotID); // if both parameters are supplied, check the given item is actually in that slot if (slot != null && childPath != null && !slot.getItemPath().equals(childPath)) { throw new ObjectNotFoundException("Item " + childPath + " was not in slot " + slotID); } members.add(slot); } else { // find the members from entity key (UUID) for (E member: getMembers().list) { if (member.getItemPath().equals(childPath)) members.add(member); } } if (members.isEmpty()) throw new ObjectNotFoundException("Could not find " + childPath + " in collection " + getName()); return members; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy