vorbaId generator constructs valid ID strings (NCNames)
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / IdFactory.java
1 /**
2  * 
3  */
4 package uk.ac.vamsas.client.simpleclient;
5
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8
9 import uk.ac.vamsas.client.ClientHandle;
10 import uk.ac.vamsas.client.SessionHandle;
11 import uk.ac.vamsas.client.UserHandle;
12 import uk.ac.vamsas.client.Vobject;
13 import uk.ac.vamsas.client.VorbaId;
14 import uk.ac.vamsas.client.VorbaIdFactory;
15 import uk.ac.vamsas.objects.utils.document.VersionEntries;
16
17 import java.util.Hashtable;
18 import java.util.zip.CRC32;
19 /**
20  * Simplest VorbaId constructor
21  * @author jimp
22  *
23  */
24 public class IdFactory extends VorbaIdFactory {
25   static Log log = LogFactory.getLog(IdFactory.class);
26   private SessionHandle session=null;
27   private ClientHandle client;
28   private UserHandle user;
29   private CRC32 unique=new CRC32(); // used to attempt a unique but predictable stream for IDs
30   private String idstring;
31   int sequence=1; // incrementing value for next new ID
32   /**
33    * 
34    */
35   public IdFactory() {
36     super();
37     // TODO Auto-generated constructor stub
38   }
39   
40   /**
41    * @param session
42    * @param client
43    * @param user
44    */
45   protected IdFactory(SessionHandle session, ClientHandle client, UserHandle user) {
46     super();
47     this.session = session;
48     this.client = client;
49     this.user = user;
50     unique.reset();
51     unique.update(new Object[] { session, client, user}.toString().getBytes());
52     // TODO: Ensure format of URNs and use standard composition methods.
53     idstring = client.getClientNCname()+"_"+unique.getValue()+".";
54     extantids=new Hashtable();
55     this.extanthashv=new Hashtable();
56   }
57   /**
58    * Create IdFactory with existing object hashes and id set
59    * @param session
60    * @param client
61    * @param user
62    * @param extanthashv hash of existing VorbaIds from a previous read of same document
63    */
64   protected IdFactory(SessionHandle session, ClientHandle client, UserHandle user, Hashtable extanthashv) {
65     this(session, client, user);
66     this.extanthashv = extanthashv;
67   }
68   /**
69    * values for keys in this hash can be used to reference the uk.ac.vamsas.client.Vobject instance for the VorbaId string.
70    * @return the hash of all VorbaIds
71    */
72   protected Hashtable getVorbaIdHash() {
73     return extantids;
74   }
75   /**
76    * values for keys in this hash are Vobjhash objects created for each Vobj with a VorbaId
77    * after this factory has been used to write a vamsas archive.
78    * @return the hash of all VorbaIds and their hash values.
79    */
80   protected Hashtable getVobjhashVals() {
81     return extanthashv;
82   }
83   /* (non-Javadoc)
84    * @see uk.ac.vamsas.client.VorbaIdFactory#makeVorbaId()
85    */
86   public VorbaId makeVorbaId(Vobject vobject) {
87     if (session==null)
88       throw new Error("makeVorbaId called on improperly initialised IdFactory Vobject!");
89     if (!vobject.isRegisterable())
90       throw new Error("makeVorbaId called on unregisterable object.");
91     if (vobject.isRegistered())
92       throw new Error("makeVorbaId called on already registered object.");
93     String newidstring;
94     do {
95       if (sequence>0) {
96         sequence++;
97       } else {
98         idstring+="1/";
99         sequence=1;
100       }
101       newidstring=idstring+Integer.toString(sequence);
102     } while (extantids.containsKey(newidstring));
103     VorbaId id = newId(newidstring); // VorbaId.hash()==newidstring.hash() so we can still recover vobject
104     extantids.put(id, vobject); // hash the Vobject by its new Id
105     return id;
106   }
107
108   /* (non-Javadoc)
109    * @see uk.ac.vamsas.client.VorbaIdFactory#setSession(uk.ac.vamsas.client.SessionHandle)
110    */
111   protected void setSession(SessionHandle sessionhandle) {
112     if (sessionhandle!=null)
113       session=sessionhandle;
114     else
115       log.warn("setSession(null) called.");
116   }
117
118   /* (non-Javadoc)
119    * @see uk.ac.vamsas.client.VorbaIdFactory#getSessionHandle()
120    */
121   public SessionHandle getSessionHandle() {
122     return session;
123   }
124
125   /* (non-Javadoc)
126    * @see uk.ac.vamsas.client.VorbaIdFactory#setClient(uk.ac.vamsas.client.ClientHandle)
127    */
128   protected void setClient(ClientHandle appHandle) {
129     if (appHandle!=null)
130       client = appHandle;
131     else
132       log.warn("setClient(null) called.");
133   }
134
135   /* (non-Javadoc)
136    * @see uk.ac.vamsas.client.VorbaIdFactory#getClientHandle()
137    */
138   public ClientHandle getClientHandle() {
139     return client;
140   }
141
142   /* (non-Javadoc)
143    * @see uk.ac.vamsas.client.VorbaIdFactory#setUser(uk.ac.vamsas.client.UserHandle)
144    */
145   protected void setUser(UserHandle userHandle) {
146   if (userHandle!=null)
147     user = userHandle;
148   else
149     log.warn("setUser(null) called.");
150   }
151
152   /* (non-Javadoc)
153    * @see uk.ac.vamsas.client.VorbaIdFactory#getUserHandle()
154    */
155   public UserHandle getUserHandle() {
156     return user;
157   }
158   /**
159    * Convenience method used for default behaviour in testing 
160    * and any anonymous internal vamsasDocument unmarshalling
161    * @param clientname
162    * @return
163    */
164   protected  static IdFactory getDummyFactory(String clientname) {
165     if (clientname==null)
166       clientname="uk.ac.vamsas.client.simpleclient.IdFactory";
167     return new IdFactory(new SessionHandle("dummy.session"), 
168         new ClientHandle(clientname,VersionEntries.latestVersion()), 
169         new UserHandle(clientname, "Arnold User's Inc."));
170   }
171 }