001: /*
002: * Copyright 2007 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.workflow;
017:
018: import java.util.List;
019: import java.util.Collections;
020:
021: /**
022: * Represents an actor in workflow process, which can be either a user or a set of pools.
023: *
024: * <p>This object is immutable.
025: */
026: public class WfActorKey {
027: private long id;
028: private List<Long> poolIds;
029: private boolean isPool;
030:
031: public WfActorKey(long id) {
032: this .id = id;
033: this .isPool = false;
034: }
035:
036: public WfActorKey(List<Long> poolIds) {
037: if (poolIds == null)
038: throw new IllegalArgumentException("Null argument: poolIds");
039: if (poolIds.size() == 0)
040: throw new IllegalArgumentException(
041: "List of pool IDs should contain at least one entry.");
042:
043: this .poolIds = Collections.unmodifiableList(poolIds);
044: this .isPool = true;
045: }
046:
047: public boolean isPool() {
048: return isPool;
049: }
050:
051: public boolean isUser() {
052: return !isPool;
053: }
054:
055: public long getUserId() {
056: if (isPool)
057: throw new IllegalStateException(
058: "getUserId should not be called on a WfActorKey object that represents a pool(s).");
059:
060: return id;
061: }
062:
063: public List<Long> getPoolIds() {
064: if (!isPool)
065: throw new IllegalStateException(
066: "getPoolIds should not be called on a WfActorKey object that represents a user.");
067:
068: return poolIds;
069: }
070:
071: public boolean equals(Object obj) {
072: if (obj instanceof WfActorKey) {
073: WfActorKey key = (WfActorKey) obj;
074: if (isPool != key.isPool)
075: return false;
076: if (isPool) {
077: return poolIds.equals(key.poolIds);
078: } else {
079: return id == key.id;
080: }
081: } else {
082: return false;
083: }
084: }
085:
086: public int hashCode() {
087: // The calculation technique for this hashcode is taken from the HashCodeBuilder
088: // of Jakarta Commons Lang, which in itself is based on techniques from the
089: // "Effective Java" book by Joshua Bloch.
090: final int iConstant = 159;
091: int iTotal = 615;
092:
093: iTotal = appendHash(isPool ? 1 : 2, iTotal, iConstant);
094: if (isPool) {
095: for (long p : poolIds)
096: iTotal = appendHash(p, iTotal, iConstant);
097: } else {
098: iTotal = appendHash(id, iTotal, iConstant);
099: }
100:
101: return iTotal;
102: }
103:
104: private int appendHash(long value, int iTotal, int iConstant) {
105: return iTotal * iConstant + ((int) (value ^ (value >> 32)));
106: }
107: }
|