· 9 years ago · Feb 07, 2017, 03:56 PM
1package com.ser.iberia;
2
3import java.io.File;
4import java.io.FileInputStream;
5import java.io.FilenameFilter;
6import java.io.IOException;
7import java.io.InputStream;
8import java.lang.reflect.Method;
9import java.sql.Connection;
10import java.sql.DriverManager;
11import java.sql.PreparedStatement;
12import java.sql.ResultSet;
13import java.sql.SQLException;
14import java.sql.Statement;
15import java.text.DateFormat;
16import java.text.ParseException;
17import java.text.SimpleDateFormat;
18import java.util.ArrayList;
19import java.util.Calendar;
20import java.util.Date;
21import java.util.HashMap;
22import java.util.HashSet;
23import java.util.List;
24import java.util.Map;
25import java.util.Properties;
26import java.util.Set;
27import java.util.concurrent.atomic.AtomicInteger;
28import java.util.regex.Matcher;
29import java.util.regex.Pattern;
30
31import org.apache.commons.io.FilenameUtils;
32import org.apache.commons.lang.ArrayUtils;
33import org.apache.log4j.Logger;
34import org.apache.tika.metadata.Metadata;
35import org.apache.tika.parser.ParseContext;
36import org.apache.tika.parser.pdf.PDFParser;
37import org.apache.tika.sax.BodyContentHandler;
38import org.sqlite.SQLiteConfig;
39import org.sqlite.SQLiteConfig.JournalMode;
40import org.sqlite.SQLiteOpenMode;
41import org.xml.sax.ContentHandler;
42
43import com.google.gson.Gson;
44import com.joestelmach.natty.DateGroup;
45import com.ser.blueline.BlueLineException;
46import com.ser.blueline.IDescriptor;
47import com.ser.blueline.IDocument;
48import com.ser.blueline.IDocumentImportFilter;
49import com.ser.blueline.IDocumentPart;
50import com.ser.blueline.IDocumentServer;
51import com.ser.blueline.IGroup;
52import com.ser.blueline.IProperties;
53import com.ser.blueline.ISerClassFactory;
54import com.ser.blueline.ISession;
55import com.ser.blueline.ISystem;
56import com.ser.blueline.ITicket;
57import com.ser.blueline.IUser;
58import com.ser.blueline.IValueDescriptor;
59import com.ser.blueline.compoundentities.DirectoryNodeType;
60import com.ser.blueline.compoundentities.IDirectoryNode;
61import com.ser.blueline.compoundentities.IDirectoryNodes;
62import com.ser.blueline.compoundentities.IDirectoryObject;
63import com.ser.blueline.metaDataComponents.IArchiveClass;
64import com.ser.blueline.metaDataComponents.IArchiveDlg;
65import com.ser.blueline.metaDataComponents.IArchiveFolderClass;
66import com.ser.blueline.security.IExtSecurityEntries;
67import com.ser.blueline.security.RecordInstanceRight;
68import com.ser.blueline.security.SecurityEntryType;
69import com.ser.blueline.security.SecurityIdentifierType;
70
71import com.ser.foldermanager.FMLinkType;
72import com.ser.foldermanager.FMNodeType;
73import com.ser.foldermanager.IElement;
74import com.ser.foldermanager.IElements;
75import com.ser.foldermanager.IFolder;
76import com.ser.foldermanager.IFolderConnection;
77import com.ser.foldermanager.IFolderDescriptor;
78import com.ser.foldermanager.IFolderDescriptors;
79import com.ser.foldermanager.INode;
80import com.ser.foldermanager.INodeDefinition;
81import com.ser.foldermanager.INodes;
82import com.ser.sedna.client.bluelineimpl.SEDNABluelineAdapterFactory;
83import com.ser.sedna.client.bluelineimpl.document.BooleanValue;
84import com.ser.sedna.client.bluelineimpl.document.IntegerValue;
85import com.ser.sedna.client.bluelineimpl.document.ValueDescriptor;
86
87import de.sst.shared.doxis4javaapi.util.Doxis4JavaApiUtil;
88/**
89 */
90public class MainProg {
91
92 final static Logger logger = Logger.getLogger(MainProg.class);
93
94 private static final boolean DUMMY_PDF_WRITE=false;
95
96 private static final String iniFileName = "Blueline.ini";
97
98 private String serverName;
99 private String port ;
100 private String customerName ;
101 private String userName ;
102 private String password ;
103
104 private static int fipsJobCount=1;
105
106 IArchiveClass archiveClass;
107 IArchiveDlg dlgArchive;
108
109
110
111
112
113 private IDocumentServer documentServer;
114 private ISerClassFactory classFactory;
115 ISession session=null;
116
117 private List<Thread> archThreads;
118 //DateFormat df ;
119 //HeidelTimeStandalone heidelTime ;
120 //Pattern datePatern = Pattern.compile(".*(?<mydate>(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d|[09][0-9])).*");
121 Pattern datePatern = Pattern.compile("(?<mydate>([1-9]|0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d|[09][0-9]))|(?<mystrdate>([1-9]|0[1-9]|[12][0-9]|3[01])(.{1,4})(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)(.{1,4})((19|20)\\d\\d|[09][0-9]))",Pattern.CASE_INSENSITIVE);
122 Pattern plainDatePatern = Pattern.compile("(?<day>[1-9]|0[1-9]|[12][0-9]|3[01])(.{1,4})(?<month>enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)(.{1,4})(?<year>(19|20)\\d\\d|[09][0-9])",Pattern.CASE_INSENSITIVE);
123
124 private Connection perConn = null;
125
126 //config properties
127 private Properties configProps;
128
129
130 String[] dateFormatStrings = {"dd-MM-yyyy","dd/MM/yyyy","dd.MM.yyyy","dd-MM-yy","dd/MM/yy","dd.MM.yy"};
131 // ...
132
133 Date tryParse(String dateString)
134 {
135 for (String formatString : dateFormatStrings )
136 {
137 try
138 {
139 return new SimpleDateFormat(formatString).parse(dateString);
140 }
141 catch (ParseException e) {}
142 }
143
144 return null;
145 }
146
147 public MainProg() {
148 //strat the helpers
149 //df = new SimpleDateFormat("yyyy-MM-dd");
150 /*heidelTime = new HeidelTimeStandalone(Language.SPANISH,
151 DocumentType.SCIENTIFIC,
152 OutputType.TIMEML,
153 "config_heidetime.properties",
154 POSTagger.STANFORDPOSTAGGER, true);*/
155
156 }
157
158 private void getPerConnection() throws ClassNotFoundException, SQLException{
159 Class.forName("org.sqlite.JDBC");
160 // c = DriverManager.getConnection("jdbc:sqlite:test.db");
161
162 //Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
163 Properties props = new Properties();
164 props.put("busy_timeout", "30000");
165 //props.put("journal_mode","WAL");
166 SQLiteConfig config = new SQLiteConfig();
167 config.setOpenMode(SQLiteOpenMode.READWRITE);
168 //config.setJournalMode(JournalMode.WAL);
169 //config.setOpenMode(SQLiteOpenMode.NOMUTEX);
170
171 perConn = config.createConnection("jdbc:sqlite:"+configProps.getProperty("Importer.ControlFile"));
172 //perConn = DriverManager.getConnection("jdbc:sqlite:"+configProps.getProperty("Importer.ControlFile"),props); //+";threading=serialized"
173 }
174
175 /**
176 * This methods files a document. A document is created which consists of only one file. This file is
177 * the content of the first content object in the first representation.
178 * @param session A valid BlueLine-session.
179 * @param archiveDlg The filing dialog to be used.
180 * @param descriptorValues A HashMap with descriptor values.
181 * @param fileName The name of the file to be archived.
182
183
184 * @return IDocument
185 * @throws BlueLineException in case of a BlueLine error. * @throws Exception in case of other errors. */
186 public IDocument archive(ISession session, IArchiveDlg archiveDlg, HashMap<String, Object[]> descriptorValues, String fileName)
187 throws BlueLineException, Exception
188 {
189 // Create a document instance. This document instance consists of one empty representation.
190 //logger.info("before getDocumentInstance");
191 IDocument doc = classFactory.getDocumentInstance(archiveDlg, session);
192 //logger.info("after getDocumentInstance");
193 // Retrieve all components from the filing dialog
194 //IComponent components[] = archiveDlg.getComponents();
195 int i;
196 boolean oneDescriptorFilled = false;
197
198 for(Map.Entry<String, Object[]> entry : descriptorValues.entrySet()){
199 IDescriptor descriptor = documentServer.getDescriptor(entry.getKey(), session);
200 //logger.debug("Finding Desc.:"+entry.getKey());
201 if(descriptor ==null){
202 throw new Exception("Invalid Descriptor:"+entry.getKey());
203 }
204 // Create a value descriptor for the descriptor instance.
205 IValueDescriptor valueDescriptor;
206 valueDescriptor = classFactory.getValueDescriptorInstance(descriptor);
207
208 // Add the value to the value descriptor
209 for(Object value:entry.getValue()){
210 if(value instanceof String){
211 valueDescriptor.addValue((String)value);
212
213 }else if (value instanceof Boolean){
214 valueDescriptor.addValue(new BooleanValue((Boolean)value,(ValueDescriptor) valueDescriptor));
215 }
216 else if (value instanceof Integer){
217 valueDescriptor.addValue( new IntegerValue((Integer) value,(ValueDescriptor) valueDescriptor) );
218 }else{
219 throw new Exception ("Error setting descriptor value, datatype not supported");
220 }
221 }
222 oneDescriptorFilled = true;
223 // Add the value descriptor to the document.
224 doc.addDescriptor(valueDescriptor);
225 logger.debug("valueDescriptor.getDisplayString():"+valueDescriptor.getDisplayString()+", Values:"+valueDescriptor.getStringValues()[0]);
226 }
227
228 // Do not archive documents which have no descriptor values set.
229 if (!oneDescriptorFilled)
230 throw new Exception("At least one descriptor must be filled.");
231
232 // For archiving the document create a file import filter and initialize it with the file
233 // which should be archived.
234 IDocumentImportFilter filter = documentServer.getDocumentImportFilter(IDocumentImportFilter.FILE);
235 filter.init(new File(configProps.getProperty("Importer.Inputpath")+fileName));
236
237 // Retrieve a content object from this filter. (Note: The filter might return multiple
238 // content objects, so better use a loop).
239 IDocumentPart docPart = filter.getNextDocumentPart();
240
241 // Now add the content object to the document.
242 doc.addPartDocument(docPart, 0);
243
244 // Close the filter
245 filter.close();
246
247 // File the document on the server.
248 documentServer.archiveDocument(doc, session, true);
249
250
251 return doc;
252 }
253
254
255 /**
256 * This method searches for the dialog of type "default" in the document class
257 * which is defined by its id.
258 * @param session A valid BlueLine session.
259 * @param archiveClass The document class.
260
261
262 * @return The filing dialog of type "DemoArchiveDlg" in this class or null, if
263 * it does not exist. * @throws BlueLineException in case of any error. */
264 public IArchiveDlg findArchiveDlgForDocumentClass(ISession session, IArchiveClass archiveClass)
265 throws BlueLineException
266 {
267 IArchiveDlg dlg = null;
268
269 if (archiveClass != null)
270 {
271 // Retrieves the dialog of type "default" from the archive class.
272 dlg = archiveClass.getArchiveDlg("default");
273 }
274 return dlg;
275 }
276
277
278 /**
279 * This method initializes the class factory and the document server instance.
280 * @param archiveServerName Host name of the web application server that hosts DOXiS4 CSB.
281 * @param archivePort Port number used by the web application server, for example 8080.
282
283
284
285 * @throws Exception in case of any error. */
286 public void initServer(String archiveServerName, String archivePort)
287 throws Exception
288 {
289 // Instantiate the class factory.
290 //Class factoryClass = Class.forName("de.serac.bluelineimpl.SERACClassFactory");
291 //classFactory = (ISerClassFactory) factoryClass.newInstance();
292 classFactory = SEDNABluelineAdapterFactory.getInstance();
293
294 // Instantiate a properties object filled with the values in the configuration file name.
295 IProperties properties = classFactory.getPropertiesInstance(iniFileName);
296
297 // Add/Change some properties for the connection to the server.
298 properties.setProperty("Global", "ArchivServerName", archiveServerName);
299 properties.setProperty("Global", "SeratioServerName", archiveServerName);
300 properties.setProperty("Global", "ArchivPort", archivePort);
301 properties.setProperty("Global", "SeratioPort", archivePort);
302 properties.setProperty("Global", "TmpDir", "C:/temp");
303
304 //Instantiate the DocumentServer now.
305 documentServer = classFactory.getDocumentServerInstance(properties);
306 }
307 /**
308 * This methods finishes the user session.
309 * @param session The session to be logged out.
310
311 * @throws BlueLineException */
312 public void logout(ISession session) throws BlueLineException
313 {
314 documentServer.logout(session);
315 }
316
317 /**
318 * This method closes the IDocumentServer object. It must be invoked, if the
319 * IDocumentServer object is no longer needed to release all used resources
320
321 * @param session ISession
322 * @throws BlueLineException in case of errors */
323 public void closeServer(ISession session)
324 {
325 if (documentServer != null)
326 {
327 try
328 {
329 documentServer.logout(session);
330 documentServer.close();
331
332 } catch (BlueLineException e)
333 {
334 logger.error("Catched Exception", e);
335 }
336 documentServer = null;
337 }
338 }
339
340 /**
341 * Logs on a user.
342 * @param systemName The name of the organization to log on to.
343 * @param userName The name of the user to log on.
344 * @param password The password of the user.
345
346
347 * @return A session object if login was succesful, null otherwise. * @throws BlueLineException in case of any error. */
348 public ISession login(String systemName, String userName, String password)
349 throws BlueLineException
350 {
351 ISession session = null;
352
353 // Retrieve the DOXiS4 CSB organization for the systemName
354 ISystem system = documentServer.getSystem(systemName);
355
356 // Login to the server
357 ITicket ticket = documentServer.login(system, userName, password.toCharArray());
358
359 // If the ticker state is valid create a session object.
360 // Note: Other ticket states are not handled here.
361 if (ticket.isValid())
362 {
363 session = documentServer.createSession(ticket);
364 }
365
366 return session;
367 }
368
369 private long stringSumChars(String inStr){
370 long result=0;
371 for(int i=0;i<inStr.length();i++){
372 result+=(long)inStr.charAt(i);
373 }
374 return result;
375 }
376
377
378
379 /**
380 * @throws Exception
381 *
382 */
383 public void pickAndArchive(AtomicInteger _stopTrigger) throws Exception{
384 AtomicInteger stopTrigger=_stopTrigger;
385
386 try{
387 //get a DB connection for this thread and put it in transaction mode
388 Properties props = new Properties();
389 props.put("busy_timeout", "30000");
390 props.put("journal_mode","WAL");
391 //conn = DriverManager.getConnection("jdbc:sqlite:data/watsonsim.db", props);
392 SQLiteConfig config = new SQLiteConfig();
393 config.setOpenMode(SQLiteOpenMode.READWRITE);
394 //config.setJournalMode(JournalMode.WAL);
395 //config.setOpenMode(SQLiteOpenMode.NOMUTEX);
396
397 Connection dbConnection = config.createConnection("jdbc:sqlite:"+configProps.getProperty("Importer.ControlFile"));
398 //Connection dbConnection = DriverManager.getConnection("jdbc:sqlite:"+configProps.getProperty("Importer.ControlFile"),props); //+";threading=serialized"
399 //dbConnection.setAutoCommit(false);
400 //get a Doxis session for this thread
401
402 ISession doxSession = login(customerName, userName, password);
403 if(doxSession==null){
404 throw new Exception("Error while login, did you provided the right user and pass?");
405 }
406 //get the util class
407 //Doxis4JavaApiUtil dxUtil = new Doxis4JavaApiUtil(doxSession, null, documentServer);
408
409
410 while(true){
411 //stop when signaled
412 if(stopTrigger.get()==1){
413 logger.info("Trigger received, stopping the archiving thread");
414 break;
415 }
416 //try to get a document to import
417 String docToProc="";
418 String docID="";
419 try {
420 Statement stmt = dbConnection.createStatement();
421 ResultSet rs=null;
422 synchronized(stopTrigger){
423 rs=stmt.executeQuery("select id,Descriptors,DocToProcess,FolderId,RecordId from TOBE_ARCHIVED where In_Process=0 limit 1");
424 }
425
426 if (rs.next()) {
427 //try to do an update
428 Statement stmtUpdate = dbConnection.createStatement();
429 int afected=0;
430 synchronized(stopTrigger){
431 afected=stmtUpdate.executeUpdate("update TOBE_ARCHIVED set In_Process=1 where id='"+rs.getString("id")+"' and In_Process=0");
432 }
433 if(afected==0){
434 //Nothing to process (dirty select), just wait
435 rs.close();stmt.close();stmtUpdate.close();
436 Thread.currentThread().sleep(1000);
437 continue;
438 }else{
439 //process the row
440 String folderID=rs.getString("FolderId");
441 String recordID=rs.getString("RecordId");
442 docToProc=rs.getString("DocToProcess");
443 docID=rs.getString("id");
444 logger.info("Processing one row:"+rs.getString("DocToProcess"));
445 HashMap<String, Object[]> archiveDescriptors = new HashMap<String, Object[]>();
446 Gson gson = new Gson();
447 Map<String, Object> desdList=gson.fromJson(rs.getString("Descriptors"), Map.class);
448 for(Map.Entry<String, Object> entry : desdList.entrySet()){
449 String type=configProps.getProperty("descType_"+entry.getKey().replaceAll("\\s+",""));
450 Object[] valueToPass;
451 switch(type){
452 case "String" :
453 valueToPass=new String[]{(String)entry.getValue()};
454 break;
455 case "StringMulti" :
456 List<String> descs = new ArrayList<>();
457 for(String val :((String)entry.getValue()).split(";")){
458 descs.add(val);
459 }
460 valueToPass=descs.toArray(new String[descs.size()]);
461 break;
462 case "Date" :
463 com.joestelmach.natty.Parser parser = new com.joestelmach.natty.Parser();
464 List<DateGroup> groups = parser.parse((String) entry.getValue());
465 Date dt = null ;
466 for(DateGroup group : groups) {
467 dt = group.getDates().get(0);
468 }
469 //DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss aaa");
470 DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
471 //Date date = (Date)formatter.parse((String) entry.getValue());
472 valueToPass=new String[]{dateFormat.format(dt)};
473 break;
474 case "Boolean" :
475 valueToPass=new Boolean[]{(Boolean)entry.getValue()};
476 break;
477 default:
478 throw new Exception("Error in field datatype, not supoorted");
479
480 }
481 logger.debug("Adding desc:"+entry.getKey().replaceAll("\\s+","")+", "+valueToPass[0]);
482 archiveDescriptors.put(configProps.getProperty("desc_"+entry.getKey().replaceAll("\\s+","")),valueToPass);
483 }
484 rs.close();stmt.close();stmtUpdate.close();
485 //logger.debug("Start Archiving");
486 //archive the document
487 IDocument archDoc=archive(doxSession,dlgArchive,archiveDescriptors,docToProc);
488 //link document to folder
489 IFolder record=doxSession.getFolderConnection().getFolder(recordID);
490 INode fld=record.getNodeByID(folderID);
491 IElements els = fld.getElements();
492 IElement e1 = els.addNew(FMLinkType.DOCUMENT);
493 e1.setLink(archDoc.getDocumentID().getID());
494
495 record.commit();
496
497 //declare the archiving process done
498 stmtUpdate = dbConnection.createStatement();
499 synchronized(stopTrigger){
500 stmtUpdate.executeUpdate("update TOBE_ARCHIVED set done=1 where id='"+docID+"'");
501 }
502 stmtUpdate.close();
503
504 logger.info("Loaded Document:"+docToProc+" in folder:"+ folderID);
505 }
506 }else{
507 //nothing to do, wait a second and continue
508 rs.close();stmt.close();
509 Thread.currentThread().sleep(1000);
510 continue;
511 }
512 //dbConnection.commit();
513 }
514 catch(Exception e){
515 e.printStackTrace();
516 //dbConnection.rollback();
517 logger.error("Error archiving Doc.:"+docToProc+", with error:"+e.getMessage());
518 Statement stmtUpdate = dbConnection.createStatement();
519 synchronized(stopTrigger){
520 stmtUpdate.executeUpdate("update TOBE_ARCHIVED set in_error=1 where id='"+docID+"'");
521 }
522 stmtUpdate.close();
523 }
524
525
526
527
528
529 }
530
531 }
532 catch (Exception e)
533 {
534 logger.error("Catched Exception", e);
535 throw e;
536 } finally
537 {
538 // Invoke closeServer, IDocumentServer is no longer needed.
539 closeServer(session);
540 perConn.close();
541 }
542
543
544
545 }
546
547 private String capitalize(final String line) {
548 return Character.toUpperCase(line.charAt(0)) + line.substring(1);
549 }
550
551 /**
552 * Method parsePdf.
553 * @throws Exception
554 */
555 @SuppressWarnings("deprecation")
556 public void startProc() throws Exception {
557 String currentModulo="";
558 //open the config file
559 configProps = new Properties();
560 FileInputStream in = new FileInputStream("config.properties");
561 configProps.load(in);
562 in.close();
563 //get connection to derby DB with loaded historic
564 getPerConnection();
565 //get importing origin Dir
566 //File rootDir = new File(configProps.getProperty("Importer.Inputpath"));
567
568 try
569 {
570 //connect to server to reuse connection
571 serverName = configProps.getProperty("Importer.serverName");
572 port = configProps.getProperty("Importer.port");
573 customerName = configProps.getProperty("Importer.customerName");
574 userName = configProps.getProperty("Importer.userName");
575 password = configProps.getProperty("Importer.password");
576 //IDirectoryObject targetDir = null;
577 initServer(serverName, port);
578 session = login(customerName, userName, password);
579
580 if(session==null){
581 throw new Exception("Error while login, did you provided the right user and pass?");
582 }
583 //get the util class
584 Doxis4JavaApiUtil dxUtil = new Doxis4JavaApiUtil(session, null, documentServer);
585
586 //set the archiving dialog
587 archiveClass = documentServer.getArchiveClassByName(session, configProps.getProperty("Importer.application"));
588 dlgArchive = findArchiveDlgForDocumentClass(session, archiveClass);
589
590
591
592
593 //launch the archiving threads
594 //set the stop condition to 0 (1 will flag all archiving threads to stop)
595 AtomicInteger stopTrigger = new AtomicInteger(0);
596
597 Runnable documentArchiver = () -> { try {
598 pickAndArchive(stopTrigger);
599 } catch (Exception e) {
600 // TODO: see what to do when the archiving thread blows...
601 e.printStackTrace();
602 } };
603 archThreads=new ArrayList<Thread>();
604 for(int i=0;i<Integer.parseInt(configProps.getProperty("Importer.threads"));i++){
605 Thread thr=new Thread(documentArchiver);
606 archThreads.add(thr);
607 thr.start();
608 }
609
610 String lotusDoc2Process=null;String lotusDoc2ProcessID=null;
611 //start processing each line in the DB
612 while(true){
613 //get a line
614 Statement stmt = perConn.createStatement(); ResultSet rs=null;
615 /*if (System.getProperty("os.name").startsWith("Windows")) {
616 // includes: Windows 2000, Windows 95, Windows 98, Windows NT, Windows Vista, Windows XP
617 rs=stmt.executeQuery("select id,filename from PENDING where in_process=0 and (length(filename)- length(replace(filename,'\\',''))=3) and filename LIKE '%.pdf' limit 1");
618 } else {*/
619 synchronized(stopTrigger){
620 rs=stmt.executeQuery("select id,filename from pending where in_process=0 and (length(filename)- length(replace(filename,'/',''))=2) and filename LIKE '%.pdf' limit 1");
621 }
622 /*}*/
623
624
625 if (rs.next()) {
626 lotusDoc2Process = rs.getString("filename");
627 lotusDoc2ProcessID = rs.getString("id");
628 Statement stmtUpdate = perConn.createStatement();
629 synchronized(stopTrigger){
630 stmtUpdate.executeUpdate("update pending set in_process=1 where id="+rs.getString("id"));
631 }
632 rs.close();stmt.close();stmtUpdate.close();
633 }else{
634 //nothing else to do
635 rs.close();stmt.close();
636 break;
637 }
638 logger.info("Got a line to process:"+lotusDoc2Process);
639
640 //validate if file or dir exists
641 if(!(new File(configProps.getProperty("Importer.Inputpath")+lotusDoc2Process)).exists()){
642 moveToError(lotusDoc2ProcessID,lotusDoc2Process,"File or Folder does not exists",stopTrigger);
643 continue;
644 }
645 //validate if it is a file or directory
646 if((new File(configProps.getProperty("Importer.Inputpath")+lotusDoc2Process)).isDirectory()){
647 moveToError(lotusDoc2ProcessID,lotusDoc2Process,"File is a directory nothing to do with it",stopTrigger);
648 continue;
649 }
650
651 //get specific metadata for the Notes PDF and child documents - invoke the method specified in config file
652 Class cls = Class.forName("com.ser.iberia.MainProg");
653 Method method = cls.getDeclaredMethod(configProps.getProperty("Importer.application"),String.class, String.class,AtomicInteger.class);
654 Map descriptorsMap=(Map) method.invoke(this,configProps.getProperty("Importer.Inputpath")+lotusDoc2Process, lotusDoc2ProcessID,stopTrigger);
655
656
657 //create the record
658 IFolderConnection c = session.getFolderConnection();
659 IFolder folder = c.createFolder();
660 //set the record permissions (read for autorizados and write for autor)
661 Set<RecordInstanceRight> setRead = new HashSet();
662 setRead.add(RecordInstanceRight.VIEW_FOLDER_CONTENTS);
663 setRead.add(RecordInstanceRight.SUBSCRIBE_NOTIFICATION);
664 Set<RecordInstanceRight> setReadWrite = new HashSet();
665 setReadWrite.add(RecordInstanceRight.UPDATE_FOLDER);
666 setReadWrite.add(RecordInstanceRight.VIEW_FOLDER_CONTENTS);
667 setReadWrite.add(RecordInstanceRight.ADD_COMMENT_ITEM);
668 setReadWrite.add(RecordInstanceRight.EDIT_COMMENT_ITEM);
669 setReadWrite.add(RecordInstanceRight.EDIT_FOLDER_DESCRIPTORS);
670 setReadWrite.add(RecordInstanceRight.SUBSCRIBE_NOTIFICATION);
671 IExtSecurityEntries<RecordInstanceRight> se =folder.getSecurityEntries();
672
673 if(descriptorsMap==null){
674 continue;
675 }
676 String UsuariosLectura=(String) descriptorsMap.get("UsuariosLectura");
677 if(UsuariosLectura.trim().compareToIgnoreCase("*")==0){
678 //all users from metrologias
679 IGroup metroGroup = documentServer.getGroupByName(session, "Metrologia");
680 se.setSecurityIdentifier(SecurityEntryType.ALLOW,metroGroup.getID(), SecurityIdentifierType.GROUP , setRead.toArray(new RecordInstanceRight[setRead.size()]));
681
682 }else{
683 //specific users from metrologias
684 for(String user : UsuariosLectura.split(",")){
685 IUser us=documentServer.getUserByLoginName(session, user);
686 if(us==null){
687 continue;
688 }
689 se.setSecurityIdentifier(SecurityEntryType.ALLOW,us.getID(), SecurityIdentifierType.PERSON , setRead.toArray(new RecordInstanceRight[setRead.size()]));
690 }
691 }
692 IUser usw=documentServer.getUserByLoginName(session, (String) descriptorsMap.get("Autor"));
693 if(usw!=null){
694 se.setSecurityIdentifier(SecurityEntryType.ALLOW,usw.getID(), SecurityIdentifierType.PERSON , setReadWrite.toArray(new RecordInstanceRight[setReadWrite.size()]));
695 }
696
697 //put full name in the user the lectura
698 String ul="";
699 for(String user : UsuariosLectura.split(",")){
700 IUser us=documentServer.getUserByLoginName(session, user);
701 if(us==null) {continue;}
702 ul=ul+";"+us.getFullName();
703 }
704 descriptorsMap.replace("UsuariosLectura", ul);
705 //create the folder
706 INode nodeDocNotes=createFolder(folder,descriptorsMap);
707 folder.commit();
708 //publish the PDF to be archived for parallel archiving
709
710 //remove the desviaciones desc
711 descriptorsMap.remove("Desviaciones");
712 descriptorsMap.put("Titulo", new File(configProps.getProperty("Importer.Inputpath")+lotusDoc2Process).getName());
713 Gson gson = new Gson();
714 String jsonRes=gson.toJson(descriptorsMap);
715 java.sql.PreparedStatement pStmt = perConn.prepareStatement("INSERT INTO TOBE_ARCHIVED (Descriptors, DocToProcess, FolderId,RecordId) VALUES(?, ?, ?,?)");
716 pStmt.setString(1, jsonRes);
717 pStmt.setString(2, lotusDoc2Process);
718 pStmt.setString(3, nodeDocNotes.getID());
719 pStmt.setString(4, folder.getID());
720 synchronized(stopTrigger){
721 pStmt.execute();
722 }
723 pStmt.close();
724 logger.info("Sent for archiving: "+lotusDoc2Process);
725 //Thread.currentThread().sleep(30000);
726 //----------------------------------directory creation uncomment
727
728
729 //set the line as done
730 Statement stmtUpdate = perConn.createStatement();
731 synchronized(stopTrigger){
732 stmtUpdate.executeUpdate("update pending set done=1 where id="+lotusDoc2ProcessID);
733 }
734 stmtUpdate.close();
735
736 //send attachements for archiving
737 INode calidadFolder=folder.getNodesByName("Documentos anexos").get(0);
738 if(calidadFolder==null){
739 throw new Exception("Error getting the calidad folder");
740 }
741 File attFolder= new File(configProps.getProperty("Importer.Inputpath")+FilenameUtils.removeExtension(new File(lotusDoc2Process).getPath())+"-ATT");
742 //check if dir exists, if not log an error
743 if(attFolder.exists()){
744 for(File fl : attFolder.listFiles()){
745 //send each file
746 descriptorsMap.put("Titulo", fl.getName());
747 jsonRes=gson.toJson(descriptorsMap);
748 pStmt = perConn.prepareStatement("INSERT INTO TOBE_ARCHIVED (Descriptors, DocToProcess, FolderId,RecordId) VALUES(?, ?, ?,?)");
749 pStmt.setString(1, jsonRes);
750 pStmt.setString(2, FilenameUtils.removeExtension(new File(lotusDoc2Process).getPath())+"-ATT/"+fl.getName());
751 pStmt.setString(3, calidadFolder.getID());
752 pStmt.setString(4, folder.getID());
753 synchronized(stopTrigger){
754 pStmt.execute();
755 }
756 pStmt.close();
757 logger.info("Sent for archiving: "+fl.getPath());
758 //set the line as done
759 /*stmtUpdate = perConn.createStatement();
760 stmtUpdate.executeUpdate("update pending set done=1,in_process=1 where filename='"+(FilenameUtils.removeExtension(new File(lotusDoc2Process).getPath())+"-ATT/"+fl.getName()).replace("\\", "/")+"'");
761 stmtUpdate.close();*/
762 PreparedStatement pstmtUpdate = perConn.prepareStatement("update pending set done=1,in_process=1 where filename=?");
763 pstmtUpdate.setString(1, (FilenameUtils.removeExtension(new File(lotusDoc2Process).getPath())+"-ATT/"+fl.getName()).replace("\\", "/"));
764 synchronized(stopTrigger){
765 pstmtUpdate.executeUpdate();
766 }
767 pstmtUpdate.close();
768 }
769 }else{
770 logger.error("Document "+lotusDoc2Process+" have no attachements directory");
771 }
772
773
774
775
776 //get all descendant attachements and publish them for archiving
777 //TODO: publish for archiving (until now only PDF of Notes docs are to be archived)
778
779
780 //TODO:check if the archivinh queue is empty: if yes stop the
781 }
782
783 //wait untill all archiving queue is done
784 int size =1;
785 while(size>0){
786 Statement stmt = perConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
787 ResultSet rs=null;
788 synchronized(stopTrigger){
789 rs=stmt.executeQuery("select count(*) as cnt from TOBE_ARCHIVED where In_Process=0 ");
790 }
791 size = rs.getInt("cnt");
792 rs.close();
793 logger.info("Waiting for archiving, more 5 sec");
794 Thread.currentThread().sleep(5000);
795 }
796 //all done, send stop trigger
797 stopTrigger.set(1);
798 //join all threads
799 for(Thread t : archThreads){
800 t.join();
801 }
802 //give some more time for closings
803 Thread.currentThread().sleep(10000);
804
805 } catch (Exception e)
806 {
807 logger.error("Catched Exception", e);
808 throw e;
809 } finally
810 {
811 // Invoke closeServer, IDocumentServer is no longer needed.
812 closeServer(session);
813 perConn.close();
814 }
815
816 }
817
818
819
820 void moveToError(String ID, String fileName, String errorMessage, AtomicInteger stopTrigger) throws SQLException{
821 Statement stmtUpdate = perConn.createStatement();
822 synchronized(stopTrigger){
823 stmtUpdate.executeUpdate("insert into docs_inerror values("+ID+",'"+fileName.replaceAll("'","''")+"','"+errorMessage.replaceAll("'","''")+"'"+")");
824 }
825 stmtUpdate.close();
826 Statement stmtUpdateErr = perConn.createStatement();
827 synchronized(stopTrigger){
828 stmtUpdateErr.executeUpdate("update pending set in_error=1 where id="+ID);
829 }
830 stmtUpdateErr.close();
831
832 }
833
834 //Metods to extract data dependign on type of application. For new applications define the method name exactly the same as defined in the properties file Importer.application
835
836
837
838 @SuppressWarnings("unchecked")
839 Map Metrologia(String lotusDoc2Process, String lotusDoc2ProcessID, AtomicInteger stopTrigger) throws Exception{
840 Map res = new HashMap<String, Object[]>();
841 Date FechaDeAlta;
842 String AnoString="";
843 String Autor="";
844 String Maquina="";
845 String NumeroInforme="";
846 String Tema="";
847 String UsuariosLectura="";
848 String Desviaciones="";
849
850 try {
851 //get the numero of informe from filename
852
853 String patternNrInf ="/(?<ano>(?:.(?!/))+?);(?<maquina>.+?);(?<nrinf>.+?).pdf";
854 Pattern s = Pattern.compile(patternNrInf, Pattern.UNICODE_CHARACTER_CLASS);
855 //Matcher m = r.matcher(new File(lotusDoc2Process).getName());
856 Matcher mS = s.matcher(lotusDoc2Process);
857 if (mS.find( )) {
858 NumeroInforme= mS.group("nrinf");
859 AnoString= mS.group("ano");
860 Maquina= mS.group("maquina");
861 }
862 if(NumeroInforme.compareToIgnoreCase("")==0){
863 throw new Exception("DOcumento PDF sin numero de informe");
864 }
865 //get all the info from this Nr Informe from the Master table
866 Statement stmt = perConn.createStatement(); ResultSet rs=null;
867 //check if it have more than one nr inf (x)
868 //String patternSiniestro ="Siniestro[\\p{Zs}\\s](?<siniestro>\\d.+?)[\\p{Zs}\\s]";
869 //Pattern s = Pattern.compile(patternSiniestro, Pattern.UNICODE_CHARACTER_CLASS);
870 String patternNrRep="(?<nrinf>.+)[\\p{Zs}\\s][(](?<repet>\\d)[)]$";
871 Pattern pPatternNrRep = Pattern.compile(patternNrRep, Pattern.UNICODE_CHARACTER_CLASS);
872 if(NumeroInforme.matches(patternNrRep)){
873 //we have repeated nr
874 Matcher repM = pPatternNrRep.matcher(NumeroInforme);
875 repM.find();
876 int nrRep= Integer.parseInt(repM.group("repet"));
877 String nrInf= repM.group("nrinf");
878
879 synchronized(stopTrigger){
880 rs=stmt.executeQuery("select * from im2016 where NrInf='"+nrInf.replaceAll("'","''")+"'"+" and "+"ano='"+AnoString.replaceAll("'","''")+"'"+" and "+"Tipo='"+Maquina.replaceAll("'","''")+"'");
881 }
882 for(int i=0;i<nrRep;i++){
883 rs.next();
884 }
885 }else{
886 //no repetition
887 synchronized(stopTrigger){
888 rs=stmt.executeQuery("select * from im2016 where NrInf='"+NumeroInforme.replaceAll("'","''")+"'"+" and "+"ano='"+AnoString.replaceAll("'","''")+"'"+" and "+"Tipo='"+Maquina.replaceAll("'","''")+"'");
889 }
890 }
891
892 if (rs.next()) {
893 /*com.joestelmach.natty.Parser parser = new com.joestelmach.natty.Parser();
894 List<DateGroup> groups = parser.parse(rs.getString("Fecha"));
895 Date dt = null ;
896 for(DateGroup group : groups) {
897 dt = group.getDates().get(0);
898 }*/
899 FechaDeAlta= new SimpleDateFormat("dd/MM/yyyy").parse(rs.getString("Fecha"));;
900 AnoString=rs.getString("Ano");
901 //logger.info("AnoString="+AnoString);
902 Autor=rs.getString("Autor");
903 Maquina=rs.getString("Tipo");
904 NumeroInforme=rs.getString("NrInf");
905 Tema=rs.getString("Tema");
906 UsuariosLectura=rs.getString("autorizados");
907 rs.close();stmt.close();
908 }else{
909 rs.close();stmt.close();
910 throw new Exception("Nr Informe inexistente en la Master Table:"+NumeroInforme);
911 }
912 res.put("FechaDeAlta", FechaDeAlta);
913 //res.put("NumeroChasis", numeroChasis);
914 res.put("Desviaciones", "Importado desde Lotus Notes");
915 res.put("AnoString",AnoString.substring(0,AnoString.length()>1024? 1024:AnoString.length()));
916 res.put("Autor",Autor.substring(0,Autor.length()>1024? 1024:Autor.length()));
917 res.put("Maquina",Maquina.substring(0, Maquina.length()>1024? 1024:Maquina.length()));
918 res.put("Numero Informe",NumeroInforme.substring(0, NumeroInforme.length()>1024? 1024:NumeroInforme.length()));
919 res.put("Tema",Tema.substring(0, Tema.length()>1024? 1024:Tema.length()));
920 res.put("UsuariosLectura",UsuariosLectura);
921 res.put("Historico", true);
922
923
924 return res;
925 }
926 catch (Exception e) {
927 moveToError(lotusDoc2ProcessID,lotusDoc2Process,"Nr Informe inexistente en la Master Table:"+NumeroInforme+",Error :"+e.getMessage(),stopTrigger);
928 logger.error("Nr Informe inexistente en la Master Table:"+NumeroInforme);
929 }
930 finally {
931
932 }
933 return null;
934
935 }
936
937
938
939
940
941
942 private INode createFolder(IFolder folder, Map<String, Object> descsMap) throws Exception{
943 //Create Folder which will store all documents for the following dir
944 //check if we still have connection
945 if (session == null)
946 {throw new Exception("Doxis Session was abruptly closed");
947 }
948
949 //create a eFolder for this directory
950
951 folder.setDatabase("PROCESOS");
952 IArchiveFolderClass afc = documentServer.getArchiveFolderClassByName(session, "Metrologia");
953 folder.init(afc);
954 folder.setFilingView(afc.getID());
955 //set folder descriptors (modulo and informes)
956 IFolderDescriptors descs = folder.getDescriptors();
957
958 for(Map.Entry<String, Object> entry : descsMap.entrySet()){
959 /*String type=configProps.getProperty("descType_"+entry.getKey());
960 Object[] valueToPass;
961 switch(type){
962 case "String" :
963 valueToPass=new String[]{(String)entry.getValue()};*/
964
965 IDescriptor descrModulo = documentServer.getDescriptorByName(entry.getKey(), session)[0];
966 IFolderDescriptor descMod = descs.addNew();
967 descMod.setID(descrModulo.getId());
968 String descRes="";
969 if(entry.getValue() instanceof String){
970 //check if it is a multi value desc
971 if(configProps.getProperty("descType_"+entry.getKey().replaceAll("\\s+",""))!=null){
972 if(configProps.getProperty("descType_"+entry.getKey().replaceAll("\\s+","")).compareToIgnoreCase("StringMulti")==0){
973 //multi value
974 for(String val: ((String)entry.getValue()).split(";")){
975 descMod.addValue(val);
976 }
977 }else{
978 //normal
979 descMod.addValue((String)entry.getValue());
980 }
981 }
982 }else if(entry.getValue() instanceof Boolean){
983 descMod.addValue(((Boolean)entry.getValue()).toString());
984 }else if(entry.getValue() instanceof Date){
985 DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
986 //Date date = (Date)formatter.parse((String) entry.getValue());
987 descMod.addValue(dateFormat.format((Date)entry.getValue()));
988 }
989
990 }
991
992 //create Documento Lotus Notes folder
993 INodes nodes = folder.getNodes();
994 INode node = nodes.addNew(FMNodeType.STATIC);
995
996 ((INodeDefinition) node).setName("Documento Lotus Notes");
997
998 return node;
999
1000 }
1001
1002 private String getRootAbrv(String currentModulo,String ROOT_ABRV) throws Exception{
1003 String rootFolder="",moduleAbrv="";
1004 switch(currentModulo){
1005 case "AU":
1006 rootFolder="Autobastidor";
1007 moduleAbrv="AU";
1008 break;
1009 case "EN_especiales":
1010 rootFolder="EN Especiales";
1011 moduleAbrv="ENES";
1012 break;
1013 case "EN_Especiales":
1014 rootFolder="EN Especiales";
1015 moduleAbrv="ENES";
1016 break;
1017 case "Finish":
1018 rootFolder="Finish";
1019 moduleAbrv="FI";
1020 break;
1021 case "Trasero Barcelona":
1022 rootFolder="Trasero Barcelona";
1023 moduleAbrv="TB";
1024 break;
1025 //---
1026 case "Trasero Barcelona - A1 Piso":
1027 rootFolder="Trasero Barcelona - A1 Piso";
1028 moduleAbrv="TraseroBCN - A1Piso";
1029 break;
1030 case "Trasero Barcelona - PIA1_A2":
1031 rootFolder="Trasero Barcelona - PIA1_A2";
1032 moduleAbrv="TraseroBCN - PIA1_A2";
1033 case "Trasero Barcelona - PIA3":
1034 rootFolder="Trasero Barcelona - PIA3";
1035 moduleAbrv="TraseroBCN - PIA3";
1036 break;
1037 case "Trasero Barcelona - SP Poste B":
1038 rootFolder="Trasero Barcelona - SP Poste B";
1039 moduleAbrv="TraseroBCN - SPPosteB";
1040 break;
1041 case "Trasero Barcelona - PDA3":
1042 rootFolder="Trasero Barcelona - PDA3";
1043 moduleAbrv="TraseroBCN - PDA3";
1044 break;
1045 case "Trasero Barcelona - PDA1_A2":
1046 rootFolder="Trasero Barcelona - PDA1_A2";
1047 moduleAbrv="TraseroBCN - PDA1_A2";
1048 break;
1049 case "Trasero Barcelona - FA3FALDON":
1050 rootFolder="Trasero Barcelona - FA3FALDON";
1051 moduleAbrv="TraseroBCN - FA3FALDON";
1052 break;
1053 case "Trasero Barcelona - FA1_A2FALDON":
1054 rootFolder="Trasero Barcelona - FA1_A2FALDON";
1055 moduleAbrv="TraseroBCN - FA1_A2FALDON";
1056 break;
1057 case "Trasero Barcelona - A3 Piso":
1058 rootFolder="Trasero Barcelona - A3 Piso";
1059 moduleAbrv="TraseroBCN - A3Piso";
1060 break;
1061 case "Trasero Barcelona - A2 Piso":
1062 rootFolder="Trasero Barcelona - A2 Piso";
1063 moduleAbrv="TraseroBCN - A2Piso";
1064 break;
1065 //---
1066 case "Trasero Vitoria":
1067 rootFolder="Trasero Vitoria";
1068 moduleAbrv="TV";
1069 break;
1070 case "Pared derecha":
1071 rootFolder="Pared derecha";
1072 moduleAbrv="PD";
1073 break;
1074 case "Modulo delantero":
1075 rootFolder="Modulo delantero";
1076 moduleAbrv="MD";
1077 break;
1078 case "Pared izquierda":
1079 rootFolder="Pared izquierda";
1080 moduleAbrv="PI";
1081 break;
1082 case "EN":
1083 //TODO: check the name daimler wants for the record folder
1084 rootFolder="EN";
1085 moduleAbrv="EN";
1086 break;
1087 default:
1088 throw new Exception ("Folder type unknow, received:"+currentModulo);
1089 }
1090 if(ROOT_ABRV.equals("ROOT")){
1091 return rootFolder;
1092 }else{
1093 return moduleAbrv;
1094 }
1095
1096 }
1097
1098
1099 /**
1100 * Method checkInforme.
1101 * @param informesInDir String[]
1102 * @param informe String
1103 * @return boolean
1104 */
1105 private boolean checkInforme(String[] informesInDir, String informe){
1106 if(informe!=null){
1107 if(informe.length()>0){
1108 if(ArrayUtils.contains(informesInDir,informe)){
1109 return true;
1110 }
1111 }else if(informe.compareTo("")==0){
1112 return true;
1113 }
1114 }
1115 return false;
1116 }
1117
1118
1119
1120 /**
1121 * Main method.
1122 *
1123 * @param args
1124 * no arguments needed
1125
1126 * @throws Exception */
1127 public static void main(String[] args) throws Exception {
1128 logger.info("Process Started");
1129 new MainProg().startProc();
1130 logger.info("Process Ended");
1131 }
1132}
1133
1134
1135
1136// /geometrias/AU/999996,666666,913806,913668,913490/Recubrimiento pelda??o.ILP.pdf
1137
1138
1139class MinimalPdf{
1140
1141 public static final String pdf=
1142 "%PDF-1.1\n"+
1143 "%¥±ë\n"+
1144 "\n"+
1145 "1 0 obj\n"+
1146 "<< /Type /Catalog\n"+
1147 "/Pages 2 0 R\n"+
1148 ">>\n"+
1149 "endobj\n"+
1150 "\n"+
1151 "2 0 obj\n"+
1152 "<< /Type /Pages\n"+
1153 "/Kids [3 0 R]\n"+
1154 "/Count 1\n"+
1155 "/MediaBox [0 0 300 144]\n"+
1156 ">>\n"+
1157 "endobj\n"+
1158 "\n"+
1159 "3 0 obj\n"+
1160 "<< /Type /Page\n"+
1161 "/Parent 2 0 R\n"+
1162 "/Resources\n"+
1163 " << /Font\n"+
1164 "<< /F1\n"+
1165 "<< /Type /Font\n"+
1166 "/Subtype /Type1\n"+
1167 "/BaseFont /Times-Roman\n"+
1168 ">>\n"+
1169 ">>\n"+
1170 ">>\n"+
1171 "/Contents 4 0 R\n"+
1172 ">>\n"+
1173 "endobj\n"+
1174 "\n"+
1175 "4 0 obj\n"+
1176 "<< /Length 55 >>\n"+
1177 "stream\n"+
1178 "BT\n"+
1179 "/F1 18 Tf\n"+
1180 "0 0 Td\n"+
1181 "(Hello World) Tj\n"+
1182 "ET\n"+
1183 "endstream\n"+
1184 "endobj\n"+
1185 "\n"+
1186 "xref\n"+
1187 "0 5\n"+
1188 "0000000000 65535 f \n"+
1189 "0000000018 00000 n \n"+
1190 "0000000077 00000 n \n"+
1191 "0000000178 00000 n \n"+
1192 "0000000457 00000 n \n"+
1193 "trailer\n"+
1194 "<< /Root 1 0 R\n"+
1195 "/Size 5\n"+
1196 ">>\n"+
1197 "startxref\n"+
1198 "565\n"+
1199 "%%EOF\n";
1200
1201}