Source code: com/flexstor/ejb/versioncontrol/workspace/WorkspaceNameCreator.java
1 /*
2 * WorkspaceNameCreator.java
3 *
4 * Copyright $Date: 2003/08/26 15:27:41 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.ejb.versioncontrol.workspace;
12
13 import java.sql.PreparedStatement;
14 import java.sql.ResultSet;
15 import java.sql.SQLException;
16 import java.text.DecimalFormat;
17 import java.util.Enumeration;
18 import java.util.Hashtable;
19 import java.util.Iterator;
20 import java.util.Vector;
21
22 import com.flexstor.common.data.TraversalInfo;
23 import com.flexstor.common.data.edit.EditData;
24 import com.flexstor.common.data.ejb.search.MultiValueData;
25 import com.flexstor.common.exceptions.ejb.EjbException;
26 import com.flexstor.ejb.PersistSessionBean;
27 import com.flexstor.ejb.bucket.persist.ServerBucketExtendData;
28 import com.flexstor.ejb.disguise.persist.ServerDisguiseExtendData;
29 import com.flexstor.ejb.edit.persist.EditHelper;
30 import com.flexstor.ejb.field.persist.ServerFieldExtendData;
31
32 /**
33 * A utility class that creates a String representing a unique Workspace name in the database.
34 * The uniqueness of the name is not guarantee beyond a short amount of time as some other
35 * process might use it as well. If two processes call this class at the same time, there is
36 * a likelyhood that they will get the same Workspace name.
37 * The name is based on the original name passed to create the workspace plus a four digit
38 * number attached at the end.
39 */
40 public class WorkspaceNameCreator
41 {
42 PersistSessionBean bean;
43
44 public WorkspaceNameCreator( PersistSessionBean bean )
45 {
46 this.bean = bean;
47 }
48
49 /**
50 * Get a unique name for a Workspace based on the name already defined in the EditData object.
51 * The new name will be the same as the original name plus a five digit number appended at the
52 * end. This method will check the Workspace application to make sure the name returned is not
53 * already in use. This method doesn't guarantee that the name will remain unique for a long
54 * period of time as some other process might use it to create a Workspace.
55 *
56 * @param editData Contains information about the Workspace
57 * @return A String identifying the unique name or null if an error happened during the creation
58 * of the unique name
59 */
60 public String getUniqueName( EditData editData )
61 throws EjbException
62 {
63 // First we need to load the disguise information to obtain the id and name of the field
64 // and bucket holding the name of the workspace. This will be used to obtain the original
65 // Workspace name in the EditData object and also to query the right table to check that
66 // the new name generated isn't already in use.
67 Vector vTraversalInfos = editData.getTraversalPathInfo();
68 if(vTraversalInfos.isEmpty())
69 return null;
70
71 TraversalInfo traversalInfo = (TraversalInfo) vTraversalInfos.elementAt(0); //First element is trav info for now.
72 ServerDisguiseExtendData disguiseData = new EditHelper(bean).getDisguiseDataObject( traversalInfo.getDisguiseId() );
73
74 if ( disguiseData != null )
75 {
76 //Returns the bucket object corresponding to bucket id.
77 ServerBucketExtendData bucketData = disguiseData.getServerBucketExtendDataObject( editData.getStructureId() );
78 Vector dataFields = bucketData.getFieldDataObjects();
79
80 Hashtable dataTable = editData.getData();
81 //Enumeration of FieldId's contained in Hashtable
82 Enumeration enumKeys = dataTable.keys();
83 String sSourceTable = "";
84 String sWorkspaceName = "";
85 // Define a label here to break out of both while and for loops at the same time
86 whileLoop:
87 while( enumKeys.hasMoreElements() )
88 {
89 Integer fieldId = (Integer) enumKeys.nextElement();
90 for ( Iterator j = dataFields.iterator(); j.hasNext(); )
91 {
92 ServerFieldExtendData fieldData = (ServerFieldExtendData) j.next();
93 if ( fieldData.getFieldName().equals("NAME") && fieldData.getId() == fieldId.intValue() )
94 {
95 MultiValueData value = ( MultiValueData )dataTable.get( fieldId );
96 sWorkspaceName = value.getFieldData()[0];
97 sSourceTable = fieldData.getSource();
98 break whileLoop;
99 }
100 }
101 }
102
103 // We will suggest a workspace name that is the same as the original but with a 5-digit number attached;
104 // in order to keep it at 5-digitwe will check if the workspace name already contains a 5-digit number at
105 // the end and we will increment this number.
106 String sDigits = sWorkspaceName.substring(sWorkspaceName.length() - 5 );
107 long i;
108 try
109 {
110 i = Long.parseLong(sDigits) + 1;
111 // Remove the suffix out of the workspace name, a new suffix will be set in place
112 sWorkspaceName = sWorkspaceName.substring(0, sWorkspaceName.indexOf(sDigits));
113 }
114 catch ( NumberFormatException nfe ) { i = 1; }
115
116 for ( ; i < 99999; i++ )
117 {
118 // Get a four digit number padded with zeros at the beginning
119 DecimalFormat df = new DecimalFormat("'0000'#");
120 String sSuffix = df.format(i);
121 sSuffix = sSuffix.substring( sSuffix.length() - 5, sSuffix.length() );
122 String sNewWorkspaceName = sWorkspaceName + sSuffix;
123
124 String sql = "SELECT NAME FROM " + sSourceTable + " WHERE NAME = ?";
125 PreparedStatement ps = null;
126 try
127 {
128 ps = bean.getConnection().prepareStatement( sql );
129 ps.setString(1, sNewWorkspaceName);
130 ResultSet result = ps.executeQuery();
131 if ( result.next() )
132 continue;
133 else
134 return sNewWorkspaceName;
135
136 }
137 catch( SQLException sqle )
138 {
139 EjbException ejbe = new EjbException( "WorkspaceNameCreator", "getUniqueName()", "SQLException", 5329);
140 ejbe.addParameter( Integer.toString( sqle.getErrorCode()) );
141 ejbe.addParameter( sqle.getMessage());
142 throw ejbe;
143 }
144 finally
145 {
146 if ( ps != null )
147 try { ps.close(); }
148 catch ( SQLException sqle ) {}
149
150 try { bean.closeConnection(); }
151 catch ( SQLException sqle) {}
152 }
153 }
154 return null; //Not unique value was found
155 }
156 else
157 return null;
158 }
159 }