Source code: com/flexstor/flexdbserver/services/asset/destination/UnmappedStructure.java
1 /*
2 * UnmappedStructure.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:34 $ 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.flexdbserver.services.asset.destination;
12
13 import java.util.Hashtable;
14 import java.util.Iterator;
15 import java.util.Vector;
16
17 import com.flexstor.common.constants.ActionPropertiesI;
18 import com.flexstor.common.data.ejb.disguiserecord.DisguiseAssetRecordData;
19 import com.flexstor.common.data.ejb.disguiserecord.DisguiseBucketRecordData;
20 import com.flexstor.common.data.ejb.disguiserecord.DisguiseFieldRecordData;
21 import com.flexstor.common.data.ejb.disguiserecord.DisguiseRecordData;
22 import com.flexstor.common.errorlogger.FlexError;
23 import com.flexstor.common.importprocessor.ImportCtlData;
24 import com.flexstor.common.importprocessor.ImportData;
25 import com.flexstor.common.importprocessor.ImportResult;
26 import com.flexstor.common.io.xfile.FlexXFile;
27 import com.flexstor.common.io.xfile.filters.XDirFilter;
28 import com.flexstor.common.io.xfile.filters.XFileFilter;
29 import com.flexstor.common.services.ServiceArgumentsI;
30 import com.flexstor.common.util.Diagnostic;
31 import com.flexstor.ejb.bucket.persist.ServerBucketExtendData;
32 import com.flexstor.ejb.disguise.persist.ServerDisguiseExtendData;
33 import com.flexstor.ejb.field.persist.ServerFieldExtendData;
34 import com.flexstor.flexdbserver.disguise.DisguiseLoader;
35 import com.flexstor.flexdbserver.disguise.DisguiseLoaderException;
36
37 public class UnmappedStructure
38 {
39 // To get the version number from MKS
40 public final static String IDENTIFIER="$Id: UnmappedStructure.java,v 1.4 2003/08/11 02:22:34 aleric Exp $";
41
42 private String sThisService;
43 private String fileSeparator;
44 private int nMaxNoOfFiles;
45 private String sDestination;
46 private int nSequenceDir;
47 private int nFilesInDir;
48
49 public ImportResult setPaths( ImportData importData, Hashtable htProperties )
50 {
51 sThisService = (String) htProperties.get("servicename");
52 fileSeparator = System.getProperty("file.separator");
53
54 // Get Role, Type and Flag values from property list (AssetService)
55 String sRoleIn = (String) htProperties.get(ServiceArgumentsI.ROLE_DATA_SOURCE);
56 String sTypeIn = (String) htProperties.get(ServiceArgumentsI.TYPE_DATA_SOURCE);
57 String sFlagIn = (String) htProperties.get(ServiceArgumentsI.FLAG_DATA_SOURCE);
58
59 // Get the maximum number of files to be moved to a single directory
60 try
61 {
62 String sMaxNoOfFiles = (String) htProperties.get("max_no_of_files");
63 nMaxNoOfFiles = Integer.valueOf(sMaxNoOfFiles).intValue();
64 }
65 catch ( NumberFormatException nfe )
66 {
67 //6920=Property %%1 was not properly defined for %%2 in configuration file.
68 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6920, new String[] {"max_no_of_files", sThisService} ) );
69 ImportResult result = new ImportResult(false);
70 result.setImportData(importData);
71 return result;
72 }
73
74 // Get the destination location
75 try
76 {
77 sDestination = (String) htProperties.get("destinationbase");
78 if ( !sDestination.endsWith(fileSeparator) )
79 sDestination += fileSeparator;
80 }
81 catch ( NullPointerException npe )
82 {
83 //6518=Destination directory not specified. Cannot proceed.
84 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6518 ) );
85 ImportResult result = new ImportResult(false);
86 result.setImportData(importData);
87 return result;
88 }
89
90 boolean bResult = true;
91 DisguiseRecordData disguiseRecord;
92 if ( importData != null && (disguiseRecord = importData.getDisguiseRecordRef()) != null )
93 {
94 Vector vAssetsIn = disguiseRecord.getAssets( sRoleIn, sTypeIn, sFlagIn );
95 if ( vAssetsIn != null && vAssetsIn.size() > 0 )
96 {
97 FlexError error;
98 if ( (error = setNextDir( vAssetsIn.size() )) == null )
99 {
100 // Map the sequence name to a field if property is set
101 // Get the Bucket Name/Field Name in which the id for the sequence numbered folder will be stored
102 if ( (error = mapSequenceToField( importData, (String)htProperties.get("map_sequence_to") )) == null )
103 {
104 if ( (error = insertPaths(vAssetsIn)) == null )
105 {
106 // Replace the HIGHFILELISTBASE with the sDestination so in next services
107 // we use it as the base path ( specially for alchemy )
108 ImportCtlData ctlData = importData.getCtlDataRef();
109 ctlData.removeItem( "HIGHFILELISTBASE", ctlData.getValuePerKey("HIGHFILELISTBASE") );
110 ctlData.addValuePerKey( "HIGHFILELISTBASE" , (new FlexXFile(sDestination)).getLocalPath() );
111 }
112 }
113 }
114 if ( error != null )
115 {
116 importData.addErrorRecord( error );
117 bResult = false;
118 }
119 }
120 else
121 {
122 //6290=Could not find assets of the following role, type and flag: %%1 %%2 %%3
123 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6290, new String[] { sRoleIn, sTypeIn, sFlagIn } ) );
124 bResult = false;
125 }
126 }
127 else
128 {
129 //6291=Cannot operate on an empty data object
130 importData.addErrorRecord( new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6291 ) );
131 bResult = false;
132 }
133
134 ImportResult result = new ImportResult(bResult);
135 result.setImportData(importData);
136 return result;
137 }
138
139 private FlexError insertPaths( Vector vAssetsIn )
140 {
141 DisguiseAssetRecordData asset;
142 for ( Iterator i = vAssetsIn.iterator(); i.hasNext(); )
143 {
144 asset = (DisguiseAssetRecordData) i.next();
145 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Destination for " + fileSeparator +
146 asset.getLocation() + asset.getFileName() + " is " + sDestination + String.valueOf(nSequenceDir) );
147 asset.addProperty( ActionPropertiesI.DESTINATION_LOCATION, sDestination + String.valueOf(nSequenceDir) );
148 }
149 return null;
150 }
151
152 private FlexError setNextDir( int nFilesInDataObject )
153 {
154 // If the # of files in the data object are more than the maximum number of files allowed per folder, failed.
155 if ( nFilesInDataObject > nMaxNoOfFiles )
156 //6933=Number of files in ImportData exceeds maximum value defined in max_no_of_files property (%%1 > %%2).
157 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6933, new String[] {String.valueOf(nFilesInDataObject), String.valueOf(nMaxNoOfFiles)} );
158
159 FlexXFile xDestination = new FlexXFile(sDestination);
160 String[] list = xDestination.list( new XDirFilter() );
161 if ( list == null || list.length == 0 )
162 //6919=Output directory doesn't exist or hasn't been set with an initial numeric sub-directory: %%1
163 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6919, new String[] {sDestination} );
164
165 nSequenceDir = 0;
166 int nNext;
167 for ( int i = 0; i < list.length; i++ )
168 {
169 try
170 {
171 nNext = Integer.valueOf(list[i]).intValue();
172 if ( nNext > nSequenceDir )
173 nSequenceDir = nNext;
174 }
175 catch ( NumberFormatException nfe ) {}
176 }
177
178 // If nDir is still zero, means that there is not a numeric directory defined
179 // therefore return null to abort this operation
180 if ( nSequenceDir == 0 )
181 //6919=Output directory doesn't exist or hasn't been set with an initial numeric sub-directory: %%1
182 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6919, new String[] {sDestination} );
183
184 FlexXFile xDir = new FlexXFile( xDestination, String.valueOf(nSequenceDir) );
185 list = xDir.list( new XFileFilter() );
186 if ( list == null || list.length == 0 )
187 {
188 // Dir is empty or doesn't exist, so add the maximum number of files
189 nFilesInDir = nMaxNoOfFiles;
190 }
191 else if ( (nMaxNoOfFiles - list.length) > 0 )
192 {
193 // Add the difference between the max # of files and the # of files already existent.
194 nFilesInDir = nMaxNoOfFiles - list.length;
195 }
196 else
197 {
198 // The directory is full, add the max # of files to the next consecutive directory
199 nSequenceDir = ++nSequenceDir;
200 nFilesInDir = nMaxNoOfFiles;
201 }
202
203 // If the # of files in the data object is greater than the number of files that can be placed in the
204 // current directory, without exceeding its capacity, roll over to the next directory; otherwise use the
205 // current directory as the destination.
206 if ( nFilesInDataObject > nFilesInDir )
207 nSequenceDir++;
208
209 return null;
210 }
211
212 private FlexError mapSequenceToField( ImportData importData, String sBucketField )
213 {
214 if ( sBucketField == null )
215 return null;
216
217 ServerDisguiseExtendData disguise;
218 try
219 {
220 // Get the application name to load the disguise
221 int nAppId = importData.getDisguiseRecordRef().getDisguiseId();
222 Diagnostic.trace(Diagnostic.APPSERVER_SERVICES, "Application Id is: " + nAppId );
223 // Load it
224 disguise = DisguiseLoader.getDisguise( nAppId );
225 if ( disguise == null )
226 //6287=%%1 Application could not be loaded.
227 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6287, new String[] {String.valueOf(nAppId)} );
228 }
229 catch ( DisguiseLoaderException rdle )
230 {
231 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, rdle );
232 }
233
234 String sBucket = sBucketField.substring(0, sBucketField.indexOf(','));
235 String sField = sBucketField.substring(sBucketField.indexOf(',') + 1);
236 sBucket = sBucket.trim();
237 sField = sField.trim();
238
239 Vector vBuckets = disguise.getBucketDataObjects();
240 Vector vFields;
241 ServerBucketExtendData bucket = null;
242 ServerFieldExtendData field = null;
243
244 for ( Iterator i = vBuckets.iterator(); i.hasNext(); )
245 {
246 bucket = (ServerBucketExtendData) i.next();
247 if ( bucket.getLabel().equals(sBucket) )
248 break;
249 else
250 bucket = null;
251 }
252
253 if ( bucket == null )
254 {
255 // 6934=%%1 is not a valid bucket label.
256 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6934, new String[] {sBucket} );
257 }
258
259 vFields = bucket.getFieldDataObjects();
260 field = null;
261 for ( Iterator k = vFields.iterator(); k.hasNext(); )
262 {
263 field = (ServerFieldExtendData) k.next();
264 if ( field.getLabel().equals(sField) )
265 break;
266 else
267 field = null;
268 }
269
270 if ( field == null )
271 {
272 // 6935=%%1 is not a valid field label for %%2 bucket.
273 return new FlexError(FlexError.CRITICAL, sThisService, IDENTIFIER, 6935, new String[] {sField, sBucket} );
274 }
275
276 setFieldValue( importData.getDisguiseRecordRef().getBuckets(), bucket, field.getId() );
277 return null;
278 }
279
280 private void setFieldValue( DisguiseBucketRecordData[] aBucketRecords, ServerBucketExtendData bucket, int nField )
281 {
282 int nBucketId = bucket.getId();
283 if ( aBucketRecords == null )
284 return;
285
286 for ( int i = 0; i < aBucketRecords.length; i++ )
287 {
288 if ( aBucketRecords[i].getBucketStructId() == nBucketId )
289 {
290 // set field
291 Vector vFields = bucket.getFieldDataObjects();
292 ServerFieldExtendData field = null;
293 DisguiseFieldRecordData[] fieldRecords = aBucketRecords[i].getValues();
294 for ( int j = 0; j < vFields.size(); j++ )
295 {
296 field = (ServerFieldExtendData) vFields.elementAt(j);
297 if ( field.getId() == nField )
298 fieldRecords[j].setValues( new String[] { String.valueOf(nSequenceDir) } );
299 }
300 }
301 else
302 setFieldValue( aBucketRecords[i].getBuckets(), bucket, nField );
303 }
304 }
305 }