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

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

/**
 * 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 with the combination of the input parameters. * * @param slotID the id of the slot * @param childPath the UUID of the item in the slots * @return the list of members * @throws ObjectNotFoundException there is not member found for the given input parameters */ public List resolveMembers(int slotID, ItemPath childPath) throws ObjectNotFoundException { // check the slot is there if it's given by id ArrayList members = new ArrayList<>(); if (slotID > -1) { CollectionMember 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 slots from entity key for (CollectionMember member: getMembers().list) { if (member.getItemPath().equals(childPath)) members.add(member); } throw new ObjectNotFoundException("Could not find " + childPath + " in collection " + getName()); } return members; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy