00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.openmobileis.database.fastobjectdb.synchro.server;
00026
00027 import java.io.BufferedInputStream;
00028 import java.io.ByteArrayInputStream;
00029 import java.io.File;
00030 import java.io.FileInputStream;
00031 import java.io.FilenameFilter;
00032 import java.io.IOException;
00033 import java.io.InputStream;
00034 import java.io.ObjectInputStream;
00035 import java.util.StringTokenizer;
00036
00037 import org.openmobileis.common.context.SessionContext;
00038 import org.openmobileis.common.context.SessionContextManager;
00039 import org.openmobileis.common.user.UserNotFoundException;
00040 import org.openmobileis.common.util.PropertiesManager;
00041 import org.openmobileis.common.util.UniqueIdGenerator;
00042 import org.openmobileis.common.util.codec.GeneralCoder;
00043 import org.openmobileis.common.util.collection.Array;
00044 import org.openmobileis.common.util.exception.BadDataFormatException;
00045 import org.openmobileis.common.util.exception.ServiceException;
00046 import org.openmobileis.database.fastobjectdb.FODBCollectionDescriptor;
00047 import org.openmobileis.database.fastobjectdb.FODBIndexDescriptor;
00048 import org.openmobileis.database.fastobjectdb.FastObjectDB;
00049 import org.openmobileis.database.fastobjectdb.db.FODBCollection;
00050 import org.openmobileis.database.fastobjectdb.db.crypto.FODBCypher;
00051 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00052 import org.openmobileis.synchro.algo.replication.SynchroAtomicObject;
00053 import org.openmobileis.synchro.algo.replication.SynchroConflicResolver;
00054 import org.openmobileis.synchro.openmsp.OpenMSPException;
00055 import org.openmobileis.synchro.openmsp.server.synctarget.OpenMSPDBSynchroTargetListener;
00056 import org.openmobileis.synchro.openmsp.server.util.FileStoreZipEntryFile;
00057 import org.openmobileis.synchro.openmsp.server.util.MemoryZipEntryFile;
00058 import org.openmobileis.synchro.openmsp.server.util.OpenMISFile;
00059 import org.openmobileis.synchro.openmsp.server.util.ZipEntryFile;
00060 import org.openmobileis.synchro.security.auth.Credential;
00061
00072 public final class FODBOpenMSPSynchroTargetWrapper extends OpenMSPDBSynchroTargetListener {
00073 private FODBSyncTarget syncService;
00074
00075 private String pregenerateddbpath;
00076
00082 public FODBOpenMSPSynchroTargetWrapper(FODBSyncTarget syncService, String pregenerateddbpath) {
00083 this(syncService);
00084 this.pregenerateddbpath = pregenerateddbpath;
00085 }
00086
00091 public FODBOpenMSPSynchroTargetWrapper(FODBSyncTarget syncService) {
00092 super();
00093
00094 this.syncService = syncService;
00095 }
00096
00097
00098
00099
00100
00101
00102 public String getTargetName() {
00103 return syncService.getCollectionName();
00104 }
00105
00106
00107
00108
00109
00110
00111 protected void connect(Credential cred) throws UserNotFoundException, ServiceException {
00112 syncService.connect(cred);
00113
00114 }
00115
00116
00117
00118
00119
00120
00121 protected void disconnect() {
00122 syncService.disconnect();
00123
00124 }
00125
00126
00127
00128
00129
00130
00131 protected SynchroConflicResolver getSynchroConflicResolver() {
00132 return syncService.getConflicResolver();
00133 }
00134
00135
00136
00137
00138
00139
00140 protected SynchroAtomicObject[] getAllModifiedAtomicObjectSince(long syncNumber) throws OpenMSPException {
00141 return syncService.getAllModifiedAtomicObjectSince(syncNumber);
00142 }
00143
00144
00145
00146
00147
00148
00149 protected void updateTargetWithSynchroObject(Object syncObject) throws OpenMSPException {
00150 syncService.updateCollectionObject(syncObject);
00151 }
00152
00153
00154
00155
00156
00157
00158 protected void deleteTargetForSynchroObjectId(String uid) throws OpenMSPException {
00159 syncService.deleteCollectionObject(uid);
00160
00161 }
00162
00163
00164
00165
00166
00167
00168 protected Object getTargetObjectWithId(String uid) throws OpenMSPException {
00169 return syncService.getCollectionObjectWithId(uid);
00170 }
00171
00178 protected int getUpdateMaxNbRow() {
00179 return syncService.getUpdateMaxNbRow();
00180 }
00181
00185 protected void processSyncActionMetaData(String metadata) throws OpenMSPException {
00186 try {
00187
00188 int index = metadata.indexOf('%');
00189 if (index != -1) {
00190 String userdata = metadata.substring(0, index);
00191 if (!userdata.startsWith("no-metadata")) {
00192 Object userdataok = this.unserializeData(userdata);
00193 this.syncService.setSendSynchroMetaData(userdataok);
00194 }
00195 if (index+1 < metadata.length())
00196 metadata = metadata.substring(index+1, metadata.length());
00197 }
00198
00199 StringTokenizer token = new StringTokenizer(metadata, ":");
00200 if (token.hasMoreTokens()) {
00201 String collectionName = token.nextToken();
00202 SessionContext context = SessionContextManager.getManager().getSessionContext();
00203 context.setAttribute("FODBSyncServiceWrapper%class", collectionName);
00204
00205
00206 String encodedcypher = token.nextToken();
00207 if (encodedcypher.equals("nocypher")) {
00208 context.removeAttribute("FODBSyncServiceWrapper%cypher");
00209 } else {
00210 FODBCypher cypher = (FODBCypher) this.unserializeData(encodedcypher);
00211 context.setAttribute("FODBSyncServiceWrapper%cypher", cypher);
00212 }
00213
00214
00215 String coldess = token.nextToken();
00216 FODBCollectionDescriptor coldesc = (FODBCollectionDescriptor) this.unserializeData(coldess);
00217 context.setAttribute("FODBSyncServiceWrapper%coldesc", coldesc);
00218
00219 int nbToken = token.countTokens();
00220 FODBIndexDescriptor[] descList = new FODBIndexDescriptor[nbToken];
00221 int i = 0;
00222 while (token.hasMoreTokens()) {
00223 String descriptor = token.nextToken();
00224 FODBIndexDescriptor desc = (FODBIndexDescriptor) this.unserializeData(descriptor);
00225 descList[i] = desc;
00226 i++;
00227 }
00228 context.setAttribute("FODBSyncServiceWrapper%desclist", descList);
00229 }
00230 } catch (IOException ex) {
00231 throw new OpenMSPException(ex);
00232 } catch (ClassNotFoundException ex) {
00233 throw new OpenMSPException(ex);
00234 }
00235
00236 }
00237
00238 private Object unserializeData(String data) throws IOException, ClassNotFoundException {
00239 byte[] b = GeneralCoder.decodeBase64(data.getBytes());
00240 ByteArrayInputStream bstr = new ByteArrayInputStream(b);
00241 try {
00242 ObjectInputStream ostr = new ObjectInputStream(bstr);
00243 return ostr.readObject();
00244 } finally {
00245 bstr.close();
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254 protected OpenMISFile[] getDatabaseImportFiles() throws OpenMSPException {
00255 if (this.pregenerateddbpath == null) {
00256 return this.generateImportDatabaseFiles();
00257 } else {
00258 return this.getPregenerateDatabaseFiles();
00259 }
00260 }
00261
00262 private synchronized OpenMISFile[] getPregenerateDatabaseFiles() throws OpenMSPException {
00263 try {
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 File dbFiles = new File(this.pregenerateddbpath);
00277 File[] colFiles = dbFiles.listFiles(new FilenameFilter() {
00278 public boolean accept(File arg0, String arg1) {
00279 return arg1.endsWith(".col");
00280 }
00281 });
00282 OpenMISFile[] retDbFiles = new OpenMISFile[colFiles.length];
00283 for (int i = 0; i < retDbFiles.length; i++) {
00284 String fileColName = colFiles[i].getName();
00285 retDbFiles[i] = new FileStoreZipEntryFile(this.pregenerateddbpath, "/" + fileColName);
00286 ((ZipEntryFile) retDbFiles[i]).setZipFileName("/dbfiles/" + this.getTargetName() + ".zip");
00287 }
00288
00289 return retDbFiles;
00290 } catch (IOException ex) {
00291 throw new OpenMSPException(ex);
00292 }
00293 }
00294
00295 private OpenMISFile[] generateImportDatabaseFiles() throws OpenMSPException {
00296 try {
00297 String installPath = PropertiesManager.getManager().getProperty("org.openmobileis.database.fastobjectdb.synchro.server.generateddb.installpath");
00298 if (installPath == null) {
00299 installPath = System.getProperty("user.dir") + File.separator + "fodbgen";
00300
00301 }
00302 SessionContext context = SessionContextManager.getManager().getSessionContext();
00303
00304 String newis = Long.toString(UniqueIdGenerator.getManager().getNewID());
00305 StringBuffer buff = new StringBuffer(installPath).append(File.separatorChar);
00306 buff.append("temp").append(File.separatorChar).append(newis);
00307 String dirPath = buff.toString();
00308 String dbRootPath = buff.toString();
00309 buff.append(File.separatorChar).append("fodb");
00310 String dbPath = buff.toString();
00311 buff.append(File.separatorChar).append(syncService.getCollectionName()).append(".col");
00312 String filePath = buff.toString();
00313 File toDelFile = new File(filePath);
00314 if (toDelFile.exists()) {
00315 toDelFile.delete();
00316 toDelFile = new File(dbPath + File.separatorChar + "fodb.db");
00317 toDelFile.delete();
00318 }
00319 FastObjectDB db = FastObjectDB.open(dbRootPath, "fodb");
00320 try {
00321
00322 FODBCollectionDescriptor coldesc = (FODBCollectionDescriptor) context.getAttribute("FODBSyncServiceWrapper%coldesc");
00323 db.createCollection(coldesc);
00324
00325
00326 FODBCypher cypher = (FODBCypher) context.getAttribute("FODBSyncServiceWrapper%cypher");
00327 if (cypher != null) {
00328 FODBCollection col = db.getCollection(syncService.getCollectionName());
00329 col.setCollectionCypher(cypher);
00330 }
00331 FODBIndexDescriptor[] descList = (FODBIndexDescriptor[]) context.getAttribute("FODBSyncServiceWrapper%desclist");
00332 for (int i = 0; i < descList.length; i++) {
00333 if (descList[i] != null) {
00334 db.addIndex(syncService.getCollectionName(), descList[i]);
00335 }
00336 }
00337
00338 Array objList = syncService.getAllCollectionObject();
00339 for (int i = 0; i < objList.size(); i++) {
00340 db.add(syncService.getCollectionName(), objList.get(i));
00341 }
00342 syncService.updateSynchroDB(db);
00343
00344 FODBCollection[] colList = db.getDatabaseCollectionArray();
00345 OpenMISFile[] retDbFiles = new OpenMISFile[colList.length];
00346 dbPath = dbPath + File.separatorChar;
00347 for (int i = 0; i < retDbFiles.length; i++) {
00348 String fileColName = colList[i].getName() + ".col";
00349 filePath = dbPath + fileColName;
00350 InputStream file = new BufferedInputStream(new FileInputStream(filePath));
00351 retDbFiles[i] = new MemoryZipEntryFile("/" + fileColName, file);
00352 ((ZipEntryFile) retDbFiles[i]).setZipFileName("/dbfiles/" + this.getTargetName() + ".zip");
00353 file.close();
00354 }
00355 return retDbFiles;
00356 } finally {
00357 toDelFile = new File(dbPath);
00358 File[] files = toDelFile.listFiles();
00359 for (int i = 0; i < files.length; i++) {
00360 files[i].delete();
00361 }
00362
00363 File todeldir = new File(dirPath+"/fodb");
00364 todeldir.delete();
00365 todeldir = new File(dirPath);
00366 todeldir.delete();
00367 }
00368 } catch (ClassNotFoundException ex) {
00369 throw new OpenMSPException(ex);
00370 } catch (BadDataFormatException ex) {
00371 throw new OpenMSPException(ex);
00372 } catch (FODBException ex) {
00373 throw new OpenMSPException(ex);
00374 } catch (IOException ex) {
00375 throw new OpenMSPException(ex);
00376 }
00377 }
00378
00379 }