4 * @author Daniel Brunier-Coulin
5 * @copyright OPEN CASCADE 2012
8 import java.text.SimpleDateFormat;
9 import java.util.ArrayList;
10 import java.util.Date;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Properties;
15 import java.io.IOException;
16 import java.sql.Connection;
17 import java.sql.DatabaseMetaData;
18 import java.sql.ResultSet;
19 import java.sql.SQLException;
21 import org.hibernate.Query;
22 import org.hibernate.Session;
23 import org.hibernate.jdbc.Work;
24 import org.apache.log4j.Logger;
25 import org.apache.lucene.index.Term;
26 import org.apache.lucene.search.BooleanClause;
27 import org.apache.lucene.search.BooleanFilter;
28 import org.apache.lucene.search.BooleanQuery;
29 import org.apache.lucene.search.FilterClause;
30 import org.apache.lucene.search.IndexSearcher;
31 import org.apache.lucene.search.ScoreDoc;
32 import org.apache.lucene.search.Sort;
33 import org.apache.lucene.search.SortField;
34 import org.apache.lucene.search.TermQuery;
35 import org.apache.lucene.search.TermsFilter;
36 import org.apache.lucene.search.TopFieldDocs;
37 import org.apache.lucene.store.Directory;
38 import org.apache.lucene.store.FSDirectory;
40 import org.splat.kernel.User;
41 import org.splat.kernel.UserDirectory;
42 import org.splat.kernel.MultiplyDefinedException;
43 import org.splat.kernel.InvalidPropertyException;
44 import org.splat.kernel.MissedPropertyException;
47 public class Database extends org.splat.kernel.Database {
49 private int uplevel = 0; // Level of database upgrade
50 private String basepath = null; // Path of the root directory of repository
52 private static Database my = null; // Singleton instance
54 protected class CreateTables extends org.splat.kernel.Database.CreateTables {
55 // ---------------------------------------------------------------------------
56 public void execute(Connection connex) throws SQLException
58 super.execute(connex);
61 String create = "CREATE TABLE `study` (" +
62 "`rid` int(10) UNSIGNED NOT NULL," +
63 "`sid` tinytext NOT NULL," +
64 "`title` tinytext NOT NULL," +
65 "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED', 'TEMPLATE') NOT NULL default 'inWORK'," +
66 "`area` enum('PRIVATE','PUBLIC','REFERENCE') NOT NULL default 'PRIVATE'," +
67 "`manager` int(10) NOT NULL," +
68 "`version` tinytext NOT NULL," +
69 "`docount` int(10) UNSIGNED NOT NULL," +
70 "`history` int(10) UNSIGNED NOT NULL," +
71 "`credate` date NOT NULL," +
72 "`lasdate` date NOT NULL," +
73 "PRIMARY KEY (`rid`)" +
74 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
75 request.execute(create);
78 create = "CREATE TABLE `scenario` (" +
79 "`rid` int(10) UNSIGNED NOT NULL," +
80 "`sid` int(10) UNSIGNED NOT NULL," +
81 "`owner` int(10) NOT NULL," +
82 "`scendex` int(3) NOT NULL," +
83 "`title` tinytext NOT NULL," +
84 "`manager` int(10) NOT NULL," +
86 "`credate` date NOT NULL," +
87 "`lasdate` date NOT NULL," +
88 "PRIMARY KEY (`rid`)" +
89 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
90 request.execute(create);
92 // Document Entity and document tag (Publication)
93 create = "CREATE TABLE `document` (" +
94 "`rid` int(10) UNSIGNED NOT NULL," +
95 "`did` tinytext NOT NULL," +
96 "`type` int(10) NOT NULL," +
97 "`step` int(10) NOT NULL," +
98 "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED','EXTERN') NOT NULL default 'inWORK'," +
99 "`name` tinytext NOT NULL," +
100 "`author` int(10) NOT NULL," +
101 "`version` tinytext," +
102 "`countag` int(10) UNSIGNED NOT NULL," +
103 "`history` int(10) NOT NULL," +
104 "`myfile` int(10) NOT NULL," +
105 "`lasdate` date NOT NULL," +
106 "PRIMARY KEY (`rid`)" +
107 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
108 request.execute(create);
109 create = "CREATE TABLE `doctag` (" +
110 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
111 "`doc` int(10) NOT NULL," +
112 "`owner` int(10) NOT NULL," +
113 "`isnew` char(1) NOT NULL," +
114 "PRIMARY KEY (`rid`)" +
115 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
116 request.execute(create);
118 create = "CREATE TABLE `doctype` (" +
119 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
120 "`name` tinytext NOT NULL," +
121 "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
122 "`step` tinytext NOT NULL," +
123 "`result` tinytext," +
124 "PRIMARY KEY (`rid`)" +
125 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
126 request.execute(create);
127 // Document types dependencies
128 create = "CREATE TABLE `docuse` (" +
129 "`owner` int(10) NOT NULL," +
130 "`rid` int(10) NOT NULL" +
131 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
132 request.execute(create);
134 // ValidationCycle related object
135 create = "CREATE TABLE `cycle` (" +
136 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
137 "`type` int(10) NOT NULL," +
138 "`publisher` int(10)," +
139 "`reviewer` int(10)," +
140 "`approver` int(10)," +
141 "`signatory` int(10)," +
142 "PRIMARY KEY (`rid`)" +
143 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
144 request.execute(create);
146 // Timestamp related object
147 create = "CREATE TABLE `stamp` (" +
148 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
149 "`type` enum('PROMOTION','REVIEW','APPROVAL','ACCEPTANCE','DISTRIBUTION','REFUSAL') NOT NULL," +
150 "`author` int(10) NOT NULL," +
151 "`date` datetime NOT NULL," +
152 "PRIMARY KEY (`rid`)" +
153 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
154 request.execute(create);
156 // KnowledgeElements objects
157 create = "CREATE TABLE `knowelm` (" +
158 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
159 "`type` int(10) NOT NULL," +
160 "`owner` int(10) NOT NULL," +
161 "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED') NOT NULL default 'inDRAFT'," +
162 "`title` tinytext NOT NULL," +
163 "`value` text NOT NULL," +
164 "`author` int(10) NOT NULL," +
165 "`date` date NOT NULL," +
166 "PRIMARY KEY (`rid`)" +
167 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
168 request.execute(create);
169 // KnowledgeElement types
170 create = "CREATE TABLE `knowtype` (" +
171 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
172 "`name` tinytext NOT NULL," +
173 "`state` enum('inWORK','inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
174 "PRIMARY KEY (`rid`)" +
175 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
176 request.execute(create);
178 // SimulationContext objects
179 create = "CREATE TABLE `contelm` (" +
180 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
181 "`type` int(10) NOT NULL," +
182 "`step` int(10) NOT NULL," +
183 "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
184 "`value` text NOT NULL," +
185 "`counter` int(10) UNSIGNED NOT NULL," +
186 "PRIMARY KEY (`rid`)" +
187 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
188 request.execute(create);
189 // SimulationContext types
190 create = "CREATE TABLE `contype` (" +
191 "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
192 "`name` tinytext NOT NULL," +
193 "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
194 "`step` int(10) NOT NULL," +
195 "PRIMARY KEY (`rid`)" +
196 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
197 request.execute(create);
199 // Many-to-many association between ProjectElement (Study and Scenario) and SimulationContext
200 create = "CREATE TABLE `projext` (" +
201 "`owner` int(10) NOT NULL," +
202 "`ordex` int(10) NOT NULL," +
203 "`rid` int(10) NOT NULL" +
204 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
205 request.execute(create);
208 create = "CREATE TABLE `file` (" +
209 "`rid` int(10) UNSIGNED NOT NULL," +
210 "`format` tinytext NOT NULL," +
211 "`path` tinytext NOT NULL," +
212 "`date` date NOT NULL," +
213 "PRIMARY KEY (`rid`)" +
214 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
215 request.execute(create);
218 create = "CREATE TABLE `refid` (" +
219 "`cycle` int(10) NOT NULL," +
220 "`base` int(10) NOT NULL," +
221 "PRIMARY KEY (`cycle`)" +
222 ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
223 request.execute(create);
226 protected class CheckVersion implements Work {
227 // --------------------------------------------
228 public void execute(Connection connex) throws SQLException
230 DatabaseMetaData dbmdata = connex.getMetaData();
231 String dbname = "simer"; //TODO: Get the name from meta-data
234 table = dbmdata.getTables(dbname, null, "study", null);
235 if (table.next()) return;
236 uplevel = -1; // Database not initialized
240 protected final static Logger logger = org.splat.kernel.Database.logger;
242 // ==============================================================================================================================
244 // ==============================================================================================================================
246 public static Database getMe () {
247 // -------------------------------
248 if (my == null) try {
251 catch (Exception error) {
252 logger.fatal("Could not access the database, reason:", error);
256 private Database () {
257 // -------------------
258 Database.getSession().doWork(new CheckVersion());
259 this.setIDPoolSize(4); // Average number of generated IDs when creating a study and versioning a document
262 // ==============================================================================================================================
263 // Public member functions
264 // ==============================================================================================================================
266 public boolean isInitialized () {
267 // -------------------------------
268 return (uplevel >= 0);
271 public void initialize () throws IOException, SQLException {
272 // -------------------------
273 logger.info("Creation of the database.");
275 // Creation of the Lucene index
276 Index.create(); // May throw IOException if the index repository is improperly configured
278 // Creation of the SIMER SQL tables
279 Session session = Database.getSession();
280 session.doWork(new CreateTables()); // May throw SQLException if the SIMER database does not exist
283 // Population of the database with customized data
287 uplevel = 0; // The database is now up-to-date
290 // ==============================================================================================================================
291 // Protected member functions
292 // ==============================================================================================================================
294 protected void configure (Properties reprop) {
295 // --------------------------------------------
296 basepath = reprop.getProperty("repository");
299 protected void populate () {
300 // --------------------------
302 // Initialization of the schema version
303 this.setSchemaVersion("D0.3"); //TODO: Get the version name from the configuration file
305 // Creation of the default system administrator
306 //TODO: Get the username password from the Hibernate configuration
307 User.Properties uprop = new User.Properties();
308 uprop.setUsername("simer")
309 .setPassword("admin")
310 .setName("Simulation")
311 .setFirstName("Manager")
312 .setDisplayName("label.sysadmin")
314 .setMailAddress("noreply@salome-platform.org");
315 uprop.disableCheck();
316 UserDirectory.createUser(uprop);
318 catch (Exception e) {
319 // Let's continue, hoping the best...
321 ProjectSettings.getMe().initialize(); // Populates the database with all necessary stuff
324 // ==============================================================================================================================
326 // ==============================================================================================================================
328 public static Study createStudy (Study.Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
329 // --------------------------------------------------------
330 Study study = new Study(sprop);
332 study.buildReference();
333 Database.getSession().save(study);
335 Index lucin = getIndex();
338 catch (IOException error) {
339 logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
340 // Continue and try to index later
345 public static void indexStudy (Study study) {
346 // -------------------------------------------
348 Study.Properties sprop = new Study.Properties();
349 List<Proxy> index = Database.selectStudiesWhere(sprop.setReference(study.getReference()));
351 if (index.size() != 0) return; // The given study is already indexed
353 Index lucin = getIndex();
354 Scenario[] scenes = study.getScenarii();
357 if (study.getProgressState() != ProgressState.inWORK) for (int i=0; i<scenes.length; i++) {
358 List<KnowledgeElement> list = scenes[i].getAllKnowledgeElements();
359 for (Iterator<KnowledgeElement> j=list.iterator(); j.hasNext(); ) {
364 catch (Exception error) {
365 logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
369 public static Index getIndex () throws IOException {
370 // -------------------------------
371 Index lucin = new Index();
372 if ( !lucin.exists() ) Index.create(); // Happens when re-indexing all studies
376 public static File getDownloadDirectory (User user) {
377 // ---------------------------------------------------
378 StringBuffer path = new StringBuffer(my.basepath).append("downloads/").append(user.getUsername()).append("/");
379 return new File(path.toString());
382 public static File getRepositoryIndexDirectory () {
383 // -------------------------------------------------
384 return new File(my.basepath + "lucin/");
387 public static String getRepositoryVaultPath () {
388 // --------------------------------------------
389 return (my.basepath + "vault/");
392 public static String getTemplatePath () {
393 // ---------------------------------------
394 return (my.basepath + "templates/");
397 public static Document selectDocument (int index) {
398 // -------------------------------------------------
399 StringBuffer query = new StringBuffer("from Document where rid='").append(index).append("'");
400 return (Document)Database.getSession().createQuery(query.toString()).uniqueResult();
403 public static Document selectDocument (String refid, String version) {
404 // --------------------------------------------------------------------
405 StringBuffer query = new StringBuffer("from Document where did='").append(refid).append("' and version='").append(version).append("'");
406 return (Document)Database.getSession().createQuery(query.toString()).uniqueResult();
409 public static KnowledgeElement selectKnowledgeElement (int index) {
410 // -----------------------------------------------------------------
411 StringBuffer query = new StringBuffer("from KnowledgeElement where rid='").append(index).append("'");
412 KnowledgeElement result = (KnowledgeElement)Database.getSession().createQuery(query.toString()).uniqueResult();
414 result.getOwnerScenario().getOwnerStudy().loadWorkflow();
418 public static List<Proxy> selectKnowledgeElementsWhere (KnowledgeElement.Properties... kprop) {
419 // ---------------------------------------------------------------------------------------------
420 List<Proxy> result = new ArrayList<Proxy>();
424 // Creation of the Lucene query
425 File indir = Database.getRepositoryIndexDirectory();
426 Directory index = FSDirectory.open(indir);
427 IndexSearcher searcher = new IndexSearcher(index, true);
428 BooleanQuery fulquery = new BooleanQuery();
430 for (int i=0; i<kprop.length; i++) {
431 BooleanQuery query = new BooleanQuery();
432 Term input; // Supposed initialized below at least by the visibility
434 Visibility area = kprop[i].getVisibility(); // Visibility
436 input = new Term("area");
437 query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
439 ProgressState state = kprop[i].getProgressState(); // State
441 input = new Term("state");
442 query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
444 String refid = kprop[i].getReference(); // Reference
446 input = new Term("ref");
447 query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
449 KnowledgeElementType type = kprop[i].getType(); // Type
451 input = new Term("type");
452 query.add(new TermQuery(input.createTerm(type.getName())), BooleanClause.Occur.MUST);
454 User manager = kprop[i].getAuthor(); // Author
455 if (manager != null) {
456 input = new Term("author");
457 query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
459 User actor = kprop[i].getActor(); // Contributor, Reviewer or Approver of the owner study
461 input = new Term("actor");
462 query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
464 String title = kprop[i].getTitle(); // Title
466 input = new Term("contents");
467 BooleanQuery critext = new BooleanQuery();
468 String operator = "AND"; // Future user input
469 BooleanClause.Occur clause = BooleanClause.Occur.MUST;
470 if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
471 String[] word = title.split(" ");
472 for (int j=0; j<word.length; j++) {
473 critext.add(new TermQuery(input.createTerm(word[j])), clause);
475 query.add(critext, BooleanClause.Occur.MUST);
477 List<SimulationContext> context = kprop[i].getSimulationContexts();
478 if (context != null && context.size() > 0) {
479 BooleanQuery critext = new BooleanQuery();
480 for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
481 SimulationContext seltext = j.next();
482 input = new Term(String.valueOf(seltext.getType().getIndex()));
483 critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
485 query.add(critext, BooleanClause.Occur.MUST);
487 fulquery.add(query, BooleanClause.Occur.SHOULD);
489 if (logger.isInfoEnabled()) {
490 logger.info("Searching knowledges by Lucene query \"" + fulquery.toString() + "\".");
492 // Creation of the knowledge filter
493 BooleanFilter filter = new BooleanFilter();
494 TermsFilter select = new TermsFilter();
495 Term mytype = new Term("class");
496 select.addTerm( mytype.createTerm("KnowledgeElement") );
497 filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
499 // Creation of the sort criteria
500 Sort sort = new Sort(new SortField("title", SortField.STRING));
503 TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
505 if (found.totalHits < 1) return result; // No study found
507 // Construction of the result list
508 ScoreDoc[] hits = found.scoreDocs;
509 for (int i=0; i<hits.length; i++) {
510 result.add( new Index.ObjectProxy(searcher.doc(hits[i].doc)) );
514 catch (Exception error) {
515 logger.error("Error during Lucene search, reason:", error);
520 public static SimulationContext selectSimulationContext (int index) {
521 // -------------------------------------------------------------------
522 StringBuffer query = new StringBuffer("from SimulationContext where rid='").append(index).append("'");
523 return (SimulationContext)Database.getSession().createQuery(query.toString()).uniqueResult();
526 public static SimulationContext selectSimulationContext (SimulationContextType celt, String value) {
527 // --------------------------------------------------------------------------------------------------
528 SimulationContext result = null;
530 SimulationContext.Properties cprop = new SimulationContext.Properties();
531 List<SimulationContext> clist = selectSimulationContextsWhere(cprop.setType(celt).setValue(value));
532 if (!clist.isEmpty()) result = clist.get(0); // Supposed being the most used one if many exist
534 catch (InvalidPropertyException error) {
535 logger.info("Attempt to select a simulation context \"" + celt.getName() + "\" with an invalid value.");
540 @SuppressWarnings("unchecked")
541 public static List<SimulationContext> selectSimulationContextsWhere (SimulationContext.Properties cprop) {
542 // --------------------------------------------------------------------------------------------------------
543 StringBuffer query = new StringBuffer("from SimulationContext");
544 String separator = " where";
545 SimulationContextType celt = cprop.getType();
546 String value = cprop.getValue();
547 ProgressState state = cprop.getProgressState();
550 if (celt != null) { query = query.append(separator).append(" type='").append(celt.getIndex()).append("'");
552 order = " order by value asc";
554 if (value != null ) { query = query.append(separator).append(" value='").append(value).append("'");
557 if (state != null ) { query = query.append(separator).append(" state='").append(state).append("'");
558 if (celt == null) order = " order by type asc";
561 return (List<SimulationContext>)Database.getSession().createQuery(query.toString()).list();
564 public static Study selectStudy (int index) {
565 // -------------------------------------------
566 StringBuffer query = new StringBuffer("from Study where rid='").append(index).append("'");
567 Study result = (Study)Database.getSession().createQuery(query.toString()).uniqueResult();
569 result.loadWorkflow();
573 public static Study selectStudy (String refid) {
574 // ----------------------------------------------
575 StringBuffer query = new StringBuffer("from Study where sid='").append(refid).append("'");
576 Study result = (Study)Database.getSession().createQuery(query.toString()).uniqueResult();
578 result.loadWorkflow();
582 public static List<Proxy> selectStudiesWhere (Study.Properties... sprop) {
583 // ------------------------------------------------------------------------
584 List<Proxy> result = new ArrayList<Proxy>();
588 // Creation of the Lucene query
589 File indir = Database.getRepositoryIndexDirectory();
590 Directory index = FSDirectory.open(indir);
591 IndexSearcher searcher = new IndexSearcher(index, true);
592 BooleanQuery fulquery = new BooleanQuery();
594 for (int i=0; i<sprop.length; i++) {
595 BooleanQuery query = new BooleanQuery();
596 Term input; // Supposed initialized below at least by the visibility
598 Visibility area = sprop[i].getVisibility(); // Visibility
600 input = new Term("area");
601 query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
603 ProgressState state = sprop[i].getProgressState(); // State
605 input = new Term("state");
606 if (state == ProgressState.inPROGRESS) {
607 BooleanQuery cristate = new BooleanQuery();
608 cristate.add(new TermQuery(input.createTerm("inWORK")), BooleanClause.Occur.SHOULD);
609 cristate.add(new TermQuery(input.createTerm("inDRAFT")), BooleanClause.Occur.SHOULD);
610 cristate.add(new TermQuery(input.createTerm("inCHECK")), BooleanClause.Occur.SHOULD);
611 query.add(cristate, BooleanClause.Occur.MUST);
613 query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
616 String refid = sprop[i].getReference(); // Reference
618 input = new Term("ref");
619 query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
621 User manager = sprop[i].getManager(); // Author
622 if (manager != null) {
623 input = new Term("author");
624 query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
626 User actor = sprop[i].getActor(); // Contributor, Reviewer or Approver
628 input = new Term("actor");
629 query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
631 String title = sprop[i].getTitle(); // Title
633 input = new Term("contents");
634 BooleanQuery critext = new BooleanQuery();
635 String operator = "AND"; // Future user input
636 BooleanClause.Occur clause = BooleanClause.Occur.MUST;
637 if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
638 String[] word = title.split(" ");
639 for (int j=0; j<word.length; j++) {
640 critext.add(new TermQuery(input.createTerm(word[j])), clause);
642 query.add(critext, BooleanClause.Occur.MUST);
644 List<SimulationContext> context = sprop[i].getSimulationContexts();
645 if (context != null && context.size() > 0) {
646 BooleanQuery critext = new BooleanQuery();
647 for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
648 SimulationContext seltext = j.next();
649 input = new Term(String.valueOf(seltext.getType().getIndex()));
650 critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
652 query.add(critext, BooleanClause.Occur.MUST);
654 fulquery.add(query, BooleanClause.Occur.SHOULD);
656 if (logger.isInfoEnabled()) {
657 logger.info("Searching studies by Lucene query \"" + fulquery.toString() + "\".");
659 // Creation of the studies filter
660 BooleanFilter filter = new BooleanFilter();
661 TermsFilter select = new TermsFilter();
662 Term mytype = new Term("class");
663 select.addTerm( mytype.createTerm("Study") );
664 filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
666 // Creation of the sort criteria
667 Sort sort = new Sort(new SortField("title", SortField.STRING));
670 TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
672 if (found.totalHits < 1) return result; // No study found
674 // Construction of the result list
675 ScoreDoc[] hits = found.scoreDocs;
676 for (int i=0; i<hits.length; i++) {
677 result.add( new Index.ObjectProxy(searcher.doc(hits[i].doc)) );
681 catch (Exception error) {
682 logger.error("Error during Lucene search, reason:", error);
687 // ==============================================================================================================================
688 // Protected services
689 // ==============================================================================================================================
691 protected static IDBuilder selectIDBuilder (int cycle) {
692 // ------------------------------------------------------
693 StringBuffer buffer = new StringBuffer("from IDBuilder where cycle='").append(cycle).append("'");
694 String qstring = buffer.toString();
695 Query query = Database.getSession().createQuery(qstring);
696 IDBuilder result = (IDBuilder)query.uniqueResult();
701 protected static IDBuilder selectIDBuilder (Date date) {
702 // ------------------------------------------------------
703 SimpleDateFormat year = new SimpleDateFormat("yyyy");
704 String cycle = year.format(date);
705 StringBuffer buffer = new StringBuffer("from IDBuilder where cycle='").append(cycle).append("'");
706 String qstring = buffer.toString();
707 Query query = Database.getSession().createQuery(qstring);
708 IDBuilder result = (IDBuilder)query.uniqueResult();