<classpathentry exported="true" kind="lib" path="lib/antlr-2.7.6.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-collections-3.1.jar"/>
<classpathentry exported="true" kind="lib" path="lib/dom4j-1.6.1.jar"/>
- <classpathentry exported="true" kind="lib" path="lib/hibernate-3.5.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/hibernate-3.5.jar" sourcepath="/3dparty_src/hibernate/hibernate-distribution-3.5.3-Final-dist.zip"/>
<classpathentry exported="true" kind="lib" path="lib/jta-1.1.jar"/>
<classpathentry exported="true" kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry exported="true" kind="lib" path="lib/lucene-core-2.9.2.jar"/>
</antcall>
</target>
- <!-- ================================================= -->
- <!-- kernel-jar: Create the kernel jar file -->
- <!-- ================================================= -->
- <target name="kernel-jar" description="create jar file in dist directory">
- <antcall target="build-splat-jar">
- <param name="jar.name" value="kernel"/>
- </antcall>
- </target>
-
- <!-- ================================================= -->
- <!-- som-jar: Create the som jar file -->
- <!-- ================================================= -->
- <target name="som-jar" description="create jar file in dist directory">
- <antcall target="build-splat-jar">
- <param name="jar.name" value="som"/>
- </antcall>
- </target>
-
<!-- ================================================= -->
<!-- jar: Build jars -->
<!-- ================================================= -->
- <target name="jar" depends="kernel-jar,som-jar,manox-jar" description="compile and create the jar file in dist directory">
+ <target name="jar" depends="manox-jar" description="compile and create the jar file in dist directory">
</target>
<!-- ================================================= -->
+++ /dev/null
-Manifest-Version: 1.0
-Class-Path:
-
+++ /dev/null
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import org.splat.som.*;
-import org.splat.kernel.Do;
-import org.splat.kernel.UserDirectory;
-import org.splat.kernel.User;
-import org.splat.kernel.Role;
-import org.splat.manox.Reader;
-import org.splat.manox.Toolbox;
-import org.splat.manox.Writer;
-
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.apache.log4j.Logger;
-
-
-public class Test {
-
- final static Logger logger = Logger.getLogger(Test.class);
-
-// ==============================================================================================================================
-// Main
-// ==============================================================================================================================
-
- public static void main(String[] args) {
-// --------------------------------------
- Session session = Database.getSession(); // Single session for multiple operations
- Transaction transax = session.beginTransaction();
-
- ProjectSettings project = ProjectSettings.getMe();
- String path = System.getProperty("user.dir");
- try {
- project.configure(path + "/src/som.xml");
- }
- catch (Exception error) {
- logger.fatal("Could not initialize the database, reason:", error);
- return;
- }
- int nargs = args.length;
- if (nargs > 0) switch (Integer.valueOf(args[0])) {
-
- case 1:
- if (!importation_of_users()) return;
- break;
-
- case 2:
- if (!create_narveos_study()) return;
- break;
-
- case 3:
- if (!create_tripoli_study()) return;
- break;
-
- case 4:
- if (!select_user_by_username()) return;
- break;
-
- case 5:
- if (!select_study_by_state()) return;
- break;
-
- case 6:
- if (!select_study_by_title()) return;
- break;
-
- case 7:
- if (!select_study_by_reference()) return;
- break;
-
- case 8:
- if (!select_study_by_context()) return;
- break;
-
- case 9:
- if (!select_document_by_reference()) return;
- break;
-
- case 10:
- if (!select_knowledge_by_context()) return;
- break;
-
- case 11:
- if (!browse_knowledge()) return;
- break;
-
- case 12:
- if (!read_wordxml_properties()) return;
- break;
-
- case 13:
- if (!read_worddoc_properties()) return;
- }
- transax.commit();
- }
-
- private static boolean importation_of_users () {
-// ----------------------------------------------
- try {
- UserDirectory.importUsers(new File("C:/Users/Daniel/Projets/Internes/SaLoMe/Workspace/org.splat/src/users.xml"));
-
-// Print of imported users
- List<User> result = UserDirectory.selectAllUsers();
- for (Iterator<User> i=result.iterator(); i.hasNext();) {
- User auser = i.next();
- Role[] role = auser.getRoles();
- String echo = "Role(s) of user " + auser.getIndex() + " (" + auser.toString() + "): " + role[0].getName();
- for (int j=1; j<role.length; j++) echo = echo + ", " + role[j].getName();
- logger.info(echo);
- }
- return true;
- }
- catch (Exception error) {
- logger.info("Reason:", error);
- return false;
- }
- }
-
- private static boolean create_narveos_study () {
-// ----------------------------------------------
- try {
-
- User.Properties uprop = new User.Properties();
- List<User> ulist = UserDirectory.selectUsersWhere(uprop.setOrganizationName("Euriware"));
- User jb = ulist.get(0); // Manager of the study
- User pd = ulist.get(1); // Author of specifications
- User hl = UserDirectory.selectUser("hl"); // Geometry expert
- User sd = UserDirectory.selectUser("sdd"); // Customer
-
-
-// Creation of the Study object
- SimpleDateFormat on = new SimpleDateFormat("dd/MM/yyyy");
- SimpleDateFormat at = new SimpleDateFormat("dd/MM/yyyy HH:mm");
- Study.Properties sprop = new Study.Properties();
-
- Date someday = on.parse("25/01/2010");
- Study mystudy = Database.createStudy(sprop.setTitle("Caractérisation du béton SERCOTER").setDate(someday).setManager(jb)
- .setDescription("Cette étude est livrée avec l'application comme exemple pour tester les fonctions de recherche et de navigation."));
-
-
-// Addition of the default scenario
- Scenario.Properties oprop = new Scenario.Properties();
- Scenario myscenar = mystudy.addScenario(oprop.setTitle("Scénario 1").setDate(someday));
-
-
-// Definition of the project team
- mystudy.addContributor(pd);
-
-
-// Addition of documents
- Step[] ownstep = mystudy.getSteps();
- Step[] nexstep = myscenar.getSteps();
- Document.Properties dprop;
- DocumentType request = Document.selectType("requirements");
- DocumentType spec = Document.selectType("specification");
- DocumentType geom = Document.selectType("geometry");
- DocumentType note = Document.selectType("memorandum");
- DocumentType delivery = Document.selectType("report"); // Final report of the study
-
-// Set of document validation cycles
- mystudy.setValidationCycle(geom, new ValidationCycle.Properties().setActor(ValidationStep.REVIEW, hl)
- .setActor(ValidationStep.APPROVAL, jb));
-// (1) Customer requirements
- dprop = new Document.Properties();
- Publication cdc = ownstep[0].createDocument(dprop.setName("Proposition technique")
- .setExternReference("GCVP-P/09-1629/V1")
- .setDate(on.parse("08/02/2010"))
- .setType(request)
- .setFormat("pdf")
- .setAuthor(sd));
- logger.info("Uploading file \"" + cdc.getSourceFile().getName() + "\" into " + cdc.value().getSaveDirectory().getPath());
- cdc.saveAs(ProgressState.EXTERN);
-
-// (2)(3) General specifications based on (using) Customer requirements
- dprop.clear();
- Publication specgen = ownstep[0].createDocument(dprop.setName("Spécifications générales")
- .setDate(on.parse("05/03/2010"))
- .setType(spec)
- .setFormat("xml")
- .setAuthor(pd));
- logger.info("Uploading file \"" + specgen.getSourceFile().getName() + "\" into " + specgen.value().getSaveDirectory().getPath());
- specgen.saveAs(ProgressState.inWORK); // Version 0.1
- specgen.addDependency(cdc);
-
- dprop.clear();
- specgen = ownstep[0].versionDocument(specgen, dprop.setDate(on.parse("12/03/2010"))
- .setDescription("Ajout de la description du scénario de calcul"));
- specgen.saveAs(ProgressState.inWORK); // Version 0.2
- specgen.addDependency(cdc);
-
-// (4) Assembly geometry based on (using) General specifications
- dprop.clear();
- Publication sercoter = nexstep[1].createDocument(dprop.setName("Assemblage SERCOTER")
- .setDate(on.parse("26/03/2010"))
- .setType(geom)
- .setFormat("sldasm")
- .setAuthor(jb));
- logger.info("Uploading file \"" + sercoter.getSourceFile().getName() + "\" into " + sercoter.value().getSaveDirectory().getPath());
- sercoter.saveAs(ProgressState.inWORK);
- sercoter.addDependency(specgen);
-
-// (5) Technical note based on (using) General specifications and Assembly geometry
- dprop.clear();
- Publication report = nexstep[1].createDocument(dprop.setName("Modifications et simplifications retenues")
- .setDate(on.parse("26/03/2010"))
- .setType(note)
- .setFormat("doc")
- .setAuthor(jb));
- logger.info("Uploading file \"" + report.getSourceFile().getName() + "\" into " + report.value().getSaveDirectory().getPath());
- report.saveAs(ProgressState.inWORK);
- report.addDependency(specgen);
- report.addDependency(sercoter);
- report.promote(on.parse("26/03/2010"));
-
-// (6) New version of General specifications
- dprop.clear();
- specgen = ownstep[0].versionDocument(specgen, dprop.setDate(on.parse("24/03/2010"))
- .setDescription("Prise en compte des retours internes"));
- specgen.saveAs(ProgressState.inDRAFT); // Version 0.3
- specgen.addDependency(cdc);
-
- specgen.review(at.parse("26/03/2010 10:15")); // Promotion to version 1.0
- specgen.attach("pdf");
- specgen.approve(at.parse("26/03/2010 16:30")).setComment("Le document peut être envoyé au client.");
- logger.info("Uploading file \"" + specgen.value().getTitle() + ".pdf\" into " + specgen.value().getSaveDirectory().getPath());
-
-// (7)
- Publication result = ownstep[1].createDocument(dprop.setName("Comparaison des résultats")
- .setDate(on.parse("16/04/2010"))
- .setType(delivery)
- .setFormat("xml")
- .setAuthor(jb));
- logger.info("Uploading file \"" + result.getSourceFile().getName() + "\" into " + result.value().getSaveDirectory().getPath());
- result.saveAs(ProgressState.inDRAFT); // Promotes the study to In-Draft
- result.review (at.parse("19/04/2010 10:15")); // Promotes the study to In-Check
-
-
-// Assignment of simulation contexts
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- SimulationContextType customer = SimulationContext.selectType("customer");
- SimulationContextType product = SimulationContext.selectType("product");
- SimulationContextType phase = SimulationContext.selectType("phase");
- SimulationContextType need = SimulationContext.selectType("need");
- SimulationContextType subject = SimulationContext.selectType("purpose");
- SimulationContextType physics = SimulationContext.selectType("physic");
- SimulationContextType object = SimulationContext.selectType("object");
- SimulationContextType part = SimulationContext.selectType("part");
- SimulationContextType model = SimulationContext.selectType("model");
- SimulationContextType element = SimulationContext.selectType("element");
- SimulationContextType shape = SimulationContext.selectType("shape");
- SimulationContextType platform = SimulationContext.selectType("platform");
- SimulationContextType module = SimulationContext.selectType("module");
- SimulationContextType component = SimulationContext.selectType("component");
-
- List<SimulationContext> ihave = mystudy.getFirstStep().getSimulationContext(customer);
- if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
- else {
- SimulationContext imported = Database.selectSimulationContext(customer, "CEA Cadarache");
- if (imported == null) {
- mystudy.addProjectContext(cprop.setType(customer).setValue("CEA Cadarache").setState(ProgressState.APPROVED));
- } else {
- mystudy.addProjectContext(imported); // Previously generated
- }
- }
- ihave = mystudy.getFirstStep().getSimulationContext(product);
- if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
- else {
- SimulationContext imported = Database.selectSimulationContext(product, "Réacteur RAPSODIE");
- if (imported == null) {
- mystudy.addProjectContext(cprop.setType(product).setValue("Réacteur RAPSODIE").setState(ProgressState.APPROVED));
- } else {
- mystudy.addProjectContext(imported); // Previously generated
- }
- }
- mystudy.addProjectContext(cprop.setType(phase).setValue("Démantèlement").setState(ProgressState.APPROVED));
- mystudy.addProjectContext(cprop.setType(need).setValue("Caractérisation du béton SERCOTER").setState(ProgressState.APPROVED));
- mystudy.addProjectContext(cprop.setType(subject).setValue("Valider les résultats d'une précédente étude").setState(ProgressState.APPROVED));
- mystudy.addProjectContext(cprop.setType(physics).setValue("Transport de particules").setState(ProgressState.APPROVED));
- nexstep[1].addSimulationContext(cprop.setType(object).setValue("Réacteur nucléaire").setState(ProgressState.APPROVED));
- nexstep[1].addSimulationContext(cprop.setType(part).setValue("Ensemble Bloc réacteur et Enceinte en béton").setState(ProgressState.APPROVED));
-// nexstep[2].addSimulationContext(cprop.setType(model).setValue("CSG"));
- nexstep[2].addSimulationContext(cprop.setType(model).setValue("Éléments finis").setState(ProgressState.APPROVED));
- nexstep[2].addSimulationContext(cprop.setType(element).setValue("Surfacique").setState(ProgressState.APPROVED));
- nexstep[2].addSimulationContext(cprop.setType(shape).setValue("Triangles").setState(ProgressState.APPROVED));
- nexstep[4].addSimulationContext(cprop.setType(platform).setValue("NARVEOS V3").setState(ProgressState.APPROVED));
- nexstep[4].addSimulationContext(cprop.setType(module).setValue("NARMER V2").setState(ProgressState.APPROVED));
- nexstep[4].addSimulationContext(cprop.setType(component).setValue("VIRTOOLS V5").setState(ProgressState.APPROVED));
-
-// Assignment of a knowledge
- KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
- KnowledgeElementType practice = KnowledgeElement.selectType("bestpractice");
- KnowledgeElementType limit = KnowledgeElement.selectType("limitation");
- KnowledgeElementType improvment = KnowledgeElement.selectType("improvement");
- kprop.setType(limit)
- .setTitle("Format du modèle géométrique")
- .setValue("Seul le format 3DXML V5 ou antérieur est supporté.")
-// .setState(ProgressState.APPROVED)
- .setAuthor(jb);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(practice)
- .setTitle("Compréhension de l'environnement")
- .setValue("Avoir une compréhension globale du débit de dose en commençant par effectuer une cartographie.")
- .setState(ProgressState.APPROVED)
- .setAuthor(jb);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(practice)
- .setTitle("Calage du modèle radiologique")
- .setValue("A partir de sources à 1 Bq/m<sup>3</sup>, faire évoluer une source à la fois et vérifier l'impact sur les points de calcul pour connaitre l'influence relative des sources.")
- .setState(ProgressState.APPROVED)
- .setAuthor(jb);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(practice)
- .setTitle("Calage du modèle radiologique")
- .setValue("Toujours faire le premier calcul sans built-up.")
- .setState(ProgressState.APPROVED)
- .setAuthor(jb);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(limit)
- .setTitle("Effets diffusés indirects")
- .setValue("L'outil ne tenant pas compte des effets diffusés indirects, faire attention à la géométrie autour des points de calcul.")
- .setState(ProgressState.APPROVED)
- .setAuthor(jb);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(improvment)
- .setTitle("Gestion des écrans")
- .setValue("Mieux gérer les multi-écrans à géométrie cylindrique.")
- .setState(ProgressState.inCHECK) // Just for testing the approve() function below
- .setAuthor(jb);
- KnowledgeElement kelm = myscenar.addKnowledgeElement(kprop);
-
- kelm.approve();
-
- mystudy.moveToPublic();
-
- logger.info("Study \"" + mystudy.getTitle() + "\" successfully created.");
- return true;
- }
- catch (Exception error) {
- logger.info("Reason:", error);
- return false;
- }
- }
-
- private static boolean create_tripoli_study () {
-// ----------------------------------------------
- User plt = UserDirectory.selectUser("sdd");
- try {
-// Creation of the Study object
- SimpleDateFormat todate = new SimpleDateFormat("dd/MM/yyyy");
- Study.Properties sprop = new Study.Properties();
-
- Date at = todate.parse("03/05/2011");
- Study mystudy = Database.createStudy(sprop.setTitle("Validation des voies de production de la plate-forme Radioprotection").setDate(at).setManager(plt));
-
-// Addition of scenarios
- Scenario.Properties oprop = new Scenario.Properties();
- Scenario myscenar = mystudy.addScenario(oprop.setTitle("Scénario Tripoli").setDate(at));
- mystudy.addScenario(oprop.setTitle("Scénario MCNP").setDate(at));
-
-// Addition of documents
- Step[] ownstep = mystudy.getSteps();
- Step[] nexstep = myscenar.getSteps();
-
- DocumentType request = Document.selectType("requirements");
- DocumentType spec = Document.selectType("specification");
- DocumentType geom = Document.selectType("geometry");
- DocumentType mesh = Document.selectType("model");
- DocumentType note = Document.selectType("memorandum");
- DocumentType delivery = Document.selectType("report"); // Final report of the study
- Document.Properties dprop;
-
- dprop = new Document.Properties();
- Publication cdc = ownstep[0].createDocument(dprop.setName("Cahier des charges")
- .setDate(todate.parse("03/05/2011"))
- .setType(request)
- .setFormat("pdf")
- .setAuthor(plt));
- logger.info("Uploading file \"" + cdc.getSourceFile().getName() + "\" into " + cdc.value().getSaveDirectory().getPath());
- cdc.saveAs(ProgressState.EXTERN);
-
- dprop = new Document.Properties();
- Publication sgen = ownstep[0].createDocument(dprop.setName("Spécifications générales")
- .setDate(todate.parse("03/05/2010"))
- .setType(spec)
- .setFormat("xml")
- .setAuthor(plt));
- logger.info("Uploading file \"" + sgen.getSourceFile().getName() + "\" into " + sgen.value().getSaveDirectory().getPath());
- sgen.saveAs(ProgressState.inDRAFT); // Version 0.1
- sgen.addDependency(cdc);
-
- dprop = new Document.Properties();
- Publication pcc = nexstep[1].createDocument(dprop.setName("Assemblage PCC")
- .setDate(todate.parse("03/05/2011"))
- .setType(geom)
- .setFormat("ProE")
- .setAuthor(plt));
- Publication doc = nexstep[1].createDocument(dprop.setName("Description de l'assemblage")
- .setDate(todate.parse("03/05/2011"))
- .setType(note)
- .setFormat("doc")
- .setAuthor(plt));
- logger.info("Uploading file \"" + pcc.getSourceFile().getName() + "\" into " + pcc.value().getSaveDirectory().getPath());
- logger.info("Uploading file \"" + doc.getSourceFile().getName() + "\" into " + doc.value().getSaveDirectory().getPath());
- pcc.saveAs(ProgressState.inDRAFT);
- doc.saveAs(ProgressState.inCHECK);
-
- pcc.review(todate.parse("08/05/2011"));
- pcc.addDependency(sgen);
- doc.addDependency(sgen);
- doc.addDependency(pcc);
-
- pcc.attach("gdml");
- logger.info("Uploading file \"" + pcc.value().getTitle() + ".gdml\" into " + pcc.value().getSaveDirectory().getPath());
-
- dprop = new Document.Properties();
- Publication csg = nexstep[2].createDocument(dprop.setName("PCC")
- .setDate(todate.parse("03/05/2011"))
- .setType(mesh)
- .setFormat("hdf")
- .setAuthor(plt));
- logger.info("Uploading file \"" + csg.getSourceFile().getName() + "\" into " + csg.value().getSaveDirectory().getPath());
- csg.saveAs(ProgressState.inDRAFT);
-
- csg.addDependency(pcc);
-
- csg.attach("gdml", "sans void space");
- csg.attach("tri", "avec void space");
- csg.attach("pdf");
- logger.info("Uploading file \"" + csg.value().getTitle() + ".tri\" into " + csg.value().getSaveDirectory().getPath());
-
- Publication result = ownstep[1].createDocument(dprop.setName("Comparaison des résultats")
- .setDate(todate.parse("17/05/2011"))
- .setType(delivery)
- .setFormat("xml")
- .setAuthor(plt));
- logger.info("Uploading file \"" + result.getSourceFile().getName() + "\" into " + result.value().getSaveDirectory().getPath());
- result.saveAs(ProgressState.inWORK); // Version 0.1
- result.promote(todate.parse("18/05/2011")); // Promotes also the study
-
-// Assignment of simulation contexts
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- SimulationContextType customer = SimulationContext.selectType("customer");
- SimulationContextType product = SimulationContext.selectType("product");
- SimulationContextType phase = SimulationContext.selectType("phase");
- SimulationContextType need = SimulationContext.selectType("need");
- SimulationContextType subject = SimulationContext.selectType("purpose");
- SimulationContextType physics = SimulationContext.selectType("physic");
- SimulationContextType object = SimulationContext.selectType("object");
- SimulationContextType part = SimulationContext.selectType("part");
- SimulationContextType model = SimulationContext.selectType("model");
- SimulationContextType element = SimulationContext.selectType("element");
- SimulationContextType shape = SimulationContext.selectType("shape");
- SimulationContextType platform = SimulationContext.selectType("platform");
- SimulationContextType module = SimulationContext.selectType("module");
-
- List<SimulationContext> ihave = mystudy.getFirstStep().getSimulationContext(customer);
- if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
- else {
- SimulationContext imported = Database.selectSimulationContext(customer, "Fonction transverse sûreté");
- if (imported == null) {
- mystudy.addProjectContext(cprop.setType(customer).setValue("Fonction transverse sûreté").setState(ProgressState.APPROVED));
- } else {
- mystudy.addProjectContext(imported); // Not generated from specifications
- }
- }
- ihave = mystudy.getFirstStep().getSimulationContext(product);
- if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
- else {
- SimulationContext imported = Database.selectSimulationContext(product, "Laser Mégajoule");
- if (imported == null) {
- mystudy.addProjectContext(cprop.setType(product).setValue("Laser Mégajoule").setState(ProgressState.APPROVED));
- } else {
- mystudy.addProjectContext(imported); // Not generated from specifications
- }
- }
- mystudy.addProjectContext(cprop.setType(phase).setValue("Dossier de Validation DSGA/SSPP").setState(ProgressState.APPROVED));
- mystudy.addProjectContext(cprop.setType(need).setValue("Validation du calcul TRIPOLI4.5 via le PlugIn Pro/E").setState(ProgressState.APPROVED));
- mystudy.addProjectContext(cprop.setType(subject).setValue("Cartographie neutronique").setState(ProgressState.APPROVED));
- mystudy.addProjectContext(Database.selectSimulationContext(physics, "Transport de particules"));
- nexstep[1].addSimulationContext(cprop.setType(object).setValue("Bâtiment LMJ").setState(ProgressState.APPROVED));
- nexstep[1].addSimulationContext(cprop.setType(part).setValue("Bât. Nord, Sud, Hall d'expériences, Hall lasers").setState(ProgressState.APPROVED));
- nexstep[2].addSimulationContext(cprop.setType(model).setValue("CSG").setState(ProgressState.APPROVED));
- nexstep[2].addSimulationContext(cprop.setType(element).setValue("Monte Carlo ").setState(ProgressState.APPROVED));
- nexstep[2].addSimulationContext(cprop.setType(shape).setValue("Combinatoire volumique").setState(ProgressState.APPROVED));
- nexstep[4].addSimulationContext(cprop.setType(platform).setValue("SALOME-TRIPOLI V2.04").setState(ProgressState.APPROVED));
- nexstep[4].addSimulationContext(cprop.setType(module).setValue("TRIPOLI4.5").setState(ProgressState.APPROVED));
-
-// Assignment of a knowledge
- KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
- KnowledgeElementType practice = KnowledgeElement.selectType("bestpractice");
- KnowledgeElementType limit = KnowledgeElement.selectType("limitation");
- KnowledgeElementType improvment = KnowledgeElement.selectType("improvement");
- kprop.setType(practice)
- .setTitle("Compréhension des modèles CAO")
- .setValue("Convertir le modèle CAO par élément (part) et constituer les assemblages sous GDML en vérifiant à chaque étape qu'il n'existe pas d'intersection entre les éléments.")
- .setState(ProgressState.APPROVED)
- .setAuthor(plt);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(practice)
- .setTitle("Génération du volume complémentaire")
- .setValue("Appliquer la génération du volume complémentaire au modèle GDML global de l'installation en sauvegardant le découpage de l'espace complémentaire en tant que volume.")
- .setState(ProgressState.APPROVED)
- .setAuthor(plt);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(limit)
- .setTitle("Découpage du volume complémentaire")
- .setValue("Inutile de découper le complémentaire pour le code TRIPOLI4.5. Les performances calculs ne sont pas meilleures.")
- .setState(ProgressState.APPROVED)
- .setAuthor(plt);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(limit)
- .setTitle("Option de pondération")
- .setValue("impossible de visualiser sous le viewer OCC les grilles de pondération dans la géométrie (temps d'affichage prohibitif).")
- .setState(ProgressState.APPROVED)
- .setAuthor(plt);
- myscenar.addKnowledgeElement(kprop);
- kprop.setType(improvment)
- .setTitle("Grille de pondération TRIPOLI4.5")
- .setValue("Faire évoluer le viewer Ray tracing pour qu'il puisse afficher les grilles de pondération et de maillage.")
- .setState(ProgressState.APPROVED)
- .setAuthor(plt);
- myscenar.addKnowledgeElement(kprop);
-
- mystudy.moveToPublic();
-
- logger.info("Study \"" + mystudy.getTitle() + "\" successfully created.");
- return true;
- }
- catch (Exception error) {
- logger.info("Reason:", error);
- return false;
- }
- }
-
- private static boolean select_user_by_username () {
-// -------------------------------------------------
- String jbt = "jbt";
- try {
- User user = UserDirectory.selectUser(jbt);
- if (user == null) {
- logger.info("User " + jbt + " not found.");
- } else {
- logger.info("User " + jbt + " found:");
- logger.info("* " + user.getDisplayName() + ", role \"" + user.getRoleNames() + "\"");
- }
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean select_study_by_state () {
-// -----------------------------------------------
- String dbc = "jbt";
- User user = UserDirectory.selectUser(dbc);
- try {
- Study.Properties criter1 = new Study.Properties().setState(ProgressState.inPROGRESS);
- Study.Properties criter2 = new Study.Properties().setState(ProgressState.inWORK).setManager(user);
- List<Proxy> result = Database.selectStudiesWhere(criter1, criter2);
- if (result.size() == 0) {
- logger.info("No study found.");
- } else {
- logger.info("Study(ies) found:");
- for (int i=0; i<result.size(); i++) {
- logger.info("* \"" + result.get(i).getTitle() + "\"");
- }
- }
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean select_study_by_title () {
-// -----------------------------------------------
- String words = "sercoter";
- try {
- Study.Properties criteria = new Study.Properties();
- List<Proxy> result = Database.selectStudiesWhere(criteria.setTitle(words));
- if (result.size() == 0) {
- logger.info("No study found with a title including \"" + words + "\".");
- } else {
- logger.info("Study(ies) found:");
- for (int i=0; i<result.size(); i++) {
- logger.info("* \"" + result.get(i).getTitle() + "\"");
- }
- }
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean select_study_by_reference () {
-// ---------------------------------------------------
- String refid = "PLM110001";
- try {
- Study study = Database.selectStudy(refid);
- if (study == null) {
- logger.info("Study " + refid + " not found.");
- return false;
- } else {
- logger.info("Study " + refid + ": " + study.getTitle() + ".");
- display_study(study);
- return true;
- }
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean select_study_by_context () {
-// -------------------------------------------------
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- SimulationContextType ctype = SimulationContext.selectType("Produit");
- List<SimulationContext> context = Database.selectSimulationContextsWhere(cprop.setType(ctype));
- for (Iterator<SimulationContext> i=context.iterator(); i.hasNext();) {
- SimulationContext reactor = i.next();
- if (reactor.getValue().equals("Réacteur RAPSODIE")) {
-
- context = new Vector<SimulationContext>();
- context.add(reactor);
-
- Study.Properties sprop = new Study.Properties();
- List<Proxy> result = Database.selectStudiesWhere(sprop.setSimulationContexts(context)
- .setState(ProgressState.inPROGRESS));
- if (result.size() == 0) {
- logger.info("Study on Réacteur RAPSODIE not found.");
- return false;
- } else {
- logger.info("Study on Réacteur RAPSODIE: " + result.get(0).getTitle() + ".");
- return true;
- }
- }
- }
- return false;
- }
-
- private static boolean select_document_by_reference () {
-// ------------------------------------------------------
- String refid = "PLM100001.02";
- String verid = "2.0.0";
- try {
- Document result = Database.selectDocument(refid, verid);
- String title = result.getTitle();
- String refdoc = result.getReference();
- logger.info("Document " + refdoc + ": " + title + ".");
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean select_knowledge_by_context () {
-// -------------------------------------------------
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- SimulationContextType ctype = SimulationContext.selectType("Produit");
- List<SimulationContext> context = Database.selectSimulationContextsWhere(cprop.setType(ctype));
- for (Iterator<SimulationContext> i=context.iterator(); i.hasNext();) {
- SimulationContext reactor = i.next();
- if (reactor.getValue().equals("Réacteur RAPSODIE")) {
-
- context = new Vector<SimulationContext>();
- context.add(reactor);
-
- KnowledgeElementType ktype = KnowledgeElement.selectType("Bonne pratique");
- KnowledgeElement.Properties sprop = new KnowledgeElement.Properties();
- List<Proxy> result = Database.selectKnowledgeElementsWhere(sprop.setSimulationContexts(context)
- .setType(ktype));
- if (result.size() == 0) {
- logger.info("Study on Réacteur RAPSODIE not found.");
- return false;
- } else {
- logger.info("Study on Réacteur RAPSODIE: " + result.get(0).getTitle() + ".");
- return true;
- }
- }
- }
- return false;
- }
-
- private static boolean display_study (Study study) {
-// --------------------------------------------------
- try {
- Step[] mystep = study.getSteps();
- Scenario[] branch = study.getScenarii();
- List<Publication> list;
-
- for (int j=0; j<mystep.length; j++) {
- Step step = mystep[j];
- list = step.getAllDocuments();
- if (list.size() == 0) continue;
- logger.info("Step 0." + j + ":");
- for (Iterator<Publication> k=list.iterator(); k.hasNext();) {
- Publication doc = k.next();
- String output = "* " + doc.value().getTitle();
- List<Publication> exports = doc.getRelations(ConvertsRelation.class);
- if (exports.size() > 0) {
- output = output + " et export(s)";
- for (Iterator<Publication> m=exports.iterator(); m.hasNext(); ) {
- output = output + " " + m.next().getSourceFile().getName();
- }
- }
- logger.info(output);
- }
- }
- for (int i=0; i<branch.length; i++) {
- Scenario scene = branch[i];
- mystep = scene.getSteps();
- for (int j=0; j<mystep.length; j++) {
- Step step = mystep[j];
- list = step.getAllDocuments();
- if (list.size() == 0) continue;
- logger.info("Step " + (i+1) + "." + j + ":");
- for (Iterator<Publication> k=list.iterator(); k.hasNext();) {
- Publication doc = k.next();
- String output = "* " + doc.value().getTitle();
- List<Publication> exports = doc.getRelations(ConvertsRelation.class);
- if (exports.size() > 0) {
- output = output + " et export(s)";
- for (Iterator<Publication> m=exports.iterator(); m.hasNext(); ) {
- output = output + " " + m.next().getSourceFile().getName();
- }
- }
- logger.info(output);
- }
- }
- }
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean browse_knowledge () {
-// ------------------------------------------
- try {
- Study study = Database.selectStudy(1);
- Scenario[] branch = study.getScenarii();
- List<KnowledgeElementType> types = KnowledgeElement.selectTypesWhere(ProgressState.APPROVED);
-
- for (int i=0; i<branch.length; i++) {
- Scenario scene = branch[i];
- List<KnowledgeElement> kelms = scene.getAllKnowledgeElements();
- Iterator<KnowledgeElement> more = kelms.iterator();
- KnowledgeElement next = null;
- if (more.hasNext()) next = more.next();
-
- for (Iterator<KnowledgeElementType> j=types.iterator(); j.hasNext();) {
- KnowledgeElementType type = j.next();
- logger.info(type.getName() + ":");
- while (next != null && next.getType().equals(type)) {
- logger.info("* " + next.getTitle() + ": " + next.getValue());
- }
- }
- }
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean read_wordxml_properties () {
-// -------------------------------------------------
- File template = new File("D:/Atelier/Eclipse/salome/org.splat/src/template.xml");
- File copy = new File("D:/Atelier/Eclipse/salome/org.splat/src/example.xml");
- try {
- if (copy.exists()) copy.delete();
- Do.copy(template, copy);
- Writer credoc = Toolbox.getWriter(copy);
- if (credoc != null) {
-
-// Setting of properties
- credoc.updateProperty("customer", "CEA Cadarache");
- credoc.updateProperty("title", "Spécifications générales");
- credoc.save();
-
-// Displaying properties
- Reader example = Toolbox.getReader(copy);
- Revision.Format convert = new Revision.Format("V%M.%m");
- String value;
- logger.info("Properties of \"" + copy.getName() + "\" document:");
-
- value = example.extractProperty("title");
- logger.info("* Title = " + value);
- value = example.extractProperty("version");
- Revision verdoc = convert.parse(value);
- logger.info("* Version = " + verdoc.toString());
- value = example.extractProperty("customer");
- logger.info("* Customer = " + value);
- value = example.extractText();
- logger.info("* Text = " + value);
- }
- return false;
- }
- catch (Exception e) {
- return false;
- }
- }
-
- private static boolean read_worddoc_properties () {
-// -------------------------------------------------
- File file = new File("D:/Atelier/Eclipse/salome/org.splat/src/example.docx");
- try {
- if (!file.exists()) return false;
-
- Reader example = Toolbox.getReader(file);
- logger.info("Properties of \"" + file.getName() + "\" document:");
- String value;
-
- value = example.extractProperty("customer");
- logger.info("* Customer = " + value);
- value = example.extractProperty("title");
- logger.info("* Title = " + value);
- value = example.extractText();
- logger.info("* Text = " + value);
- return false;
- }
- catch (Exception e) {
- return false;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<workflow name="Cast3M">
-
-<!-- 1. Simulation Contexts
- Defines the default simulation contexts common to all studies applying this workflow. These simulation contexts
- will automatically be assigned to studies at creation time.
- Each simulation context is set through a tag corresponding to the name of a simulation context type previously
- defined in the SOM structure.
- -->
- <contexts>
- <model value="FEM"/>
- <platform value="SALOME"/>
- <module value="Cast3M"/>
- </contexts>
-
-<!-- 2. User activities
- Defines the steps involved in this workflow.
- Each step is defined by a tag corresponding to the name of a step type previously defined in the SOM structure.
- It includes:
- - The simulation contexts types relative to the step (tag classification, attribute context)
- - The document types that can be produced at this step (tag flow, attribute contents)
- - The document type result of this step (tag flow, attribute result)
- All simulation contexts and document types must previously be defined in the SOM structure.
-
- User activities are ordered. They can be attached to scenarios - they are the same for all scenarios of the study -
- or to the study itself. Attaching an activity to the study makes the data produced during this activity shared by all
- scenarios of the study (typically, the study requirements).
-
- Remarks:
- - Simulation Contexts must be attached to one classification step only.
- - Result document types must be results of one step only and be part of contents of the corresponding step.
- - The result document type of the last activity attached to the study makes the result document type of the study itself.
- -->
- <activities>
- <specification>
- <classification context="customer,product,phase,need,purpose,physic"/>
- <flow contents="requirements,specification,minutes" result="specification"/>
- </specification>
- <scenario>
- <design>
- <flow contents="design,memorandum,minutes" result="design"/>
- </design>
- <modeling>
- <classification context="object,part,geometry"/>
- <flow contents="geometry,memorandum,minutes" result="geometry"/>
- </modeling>
- <meshing>
- <classification context="model,element,shape,order"/>
- <flow contents="model,memorandum,minutes" result="model"/>
- </meshing>
- <preprocessing>
- <classification context="analysis"/>
- <flow contents="loads,script,minutes" result="loads"/>
- </preprocessing>
- <solving>
- <classification context="platform,module,component"/>
- <flow contents="log,results,minutes" result="results"/>
- </solving>
- <postprocessing>
- <flow contents="memorandum,minutes"/>
- </postprocessing>
- <capitalization>
- <flow contents="knowledge"/>
- </capitalization>
- </scenario>
- <reporting>
- <flow contents="report,minutes" result="report"/>
- </reporting>
- </activities>
-
-
-<!-- 3. Document validation cycles
- The validation cycles define the actors involved in the validation steps of documents. These steps can be
- "review", "approval" and "acceptance" and applies to document types resulting from an activity.
- Each validation cycle is defined by a tag corresponding to the type of the result document previously defined
- in activities.
-
- Remarks:
- - The actors of validation steps can be
- "manager", referring the responsible of study,
- "Nx1", referring the manager of the department (n+1 of the responsible of study),
- "Nx2", referring the boss of the department manager (n+2 of the responsible of study),
- "customer" (most likely involved in the acceptance step).
- -->
- <validations>
- <specification review="Nx1" approval="Nx2"/>
- <report review="Nx1" approval="Nx2"/>
- <default review="manager" />
- </validations>
-
-</workflow>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
-
-<hibernate-configuration>
-
- <session-factory>
- <!-- Database connection settings -->
- <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="connection.url">jdbc:mysql://localhost/simer</property>
- <property name="connection.username">simer</property>
- <property name="connection.password">admin</property>
-
- <!-- JDBC connection pool (use the built-in) -->
- <property name="connection.pool_size">1</property>
- <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
-
- <!-- SQL dialect -->
- <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
-
- <!-- Enable Hibernate's automatic session context management -->
- <property name="current_session_context_class">thread</property>
-
- <!-- Echo all executed SQL statements to stdout -->
- <property name="hibernate.show_sql">false</property>
-
- <!-- mapping files -->
- <mapping resource="org/splat/kernel/Persistent.hbm.xml" />
- <mapping resource="org/splat/kernel/Any.hbm.xml" />
- <mapping resource="org/splat/kernel/Entity.hbm.xml" />
- <mapping resource="org/splat/kernel/Attribute.hbm.xml" />
- <mapping resource="org/splat/kernel/Relation.hbm.xml" />
- <mapping resource="org/splat/kernel/IDPool.hbm.xml" />
- <mapping resource="org/splat/kernel/TextAttribute.hbm.xml" />
- <mapping resource="org/splat/kernel/Text.hbm.xml" />
- <mapping resource="org/splat/kernel/User.hbm.xml" />
-
- <mapping resource="org/splat/som/ProjectElement.hbm.xml" />
- <mapping resource="org/splat/som/Study.hbm.xml" />
- <mapping resource="org/splat/som/Scenario.hbm.xml" />
- <mapping resource="org/splat/som/Attributes.hbm.xml" />
- <mapping resource="org/splat/som/Relations.hbm.xml" />
- <mapping resource="org/splat/som/File.hbm.xml" />
- <mapping resource="org/splat/som/Document.hbm.xml" />
- <mapping resource="org/splat/som/Publication.hbm.xml" />
- <mapping resource="org/splat/som/ValidationCycle.hbm.xml" />
- <mapping resource="org/splat/som/Timestamp.hbm.xml" />
- <mapping resource="org/splat/som/SimulationContext.hbm.xml" />
- <mapping resource="org/splat/som/KnowledgeElement.hbm.xml" />
- <mapping resource="org/splat/som/IDBuilder.hbm.xml" />
-
- </session-factory>
-
-</hibernate-configuration>
\ No newline at end of file
+++ /dev/null
-### direct log messages to stdout ###
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.Target=System.out
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
-
-### set log levels - for more verbose logging change 'info' to 'debug' ###
-
-log4j.rootLogger=debug, stdout
-
-log4j.logger.org.hibernate=info
-#log4j.logger.org.hibernate=debug
-
-### log HQL query parser activity
-#log4j.logger.org.hibernate.hql.ast.AST=debug
-
-### log just the SQL
-log4j.logger.org.hibernate.SQL=debug
-
-### log JDBC bind parameters ###
-log4j.logger.org.hibernate.type=info
-#log4j.logger.org.hibernate.type=trace
-
-### log schema export/update ###
-log4j.logger.org.hibernate.tool.hbm2ddl=info
-
-### log HQL parse trees
-#log4j.logger.org.hibernate.hql=debug
-
-### log cache activity ###
-log4j.logger.org.hibernate.cache=info
-
-### log transaction activity
-#log4j.logger.org.hibernate.transaction=debug
-
-### log JDBC resource acquisition
-#log4j.logger.org.hibernate.jdbc=debug
-
-### enable the following line if you want to track down connection ###
-### leakages when using DriverManagerConnectionProvider ###
-#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the root abstract class supporting dynamic attributes.
- - All objects instance of a subclass of Any are uniquely identified by the rid primary key through the IDGenerator identifier generator class.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.Any" abstract="true">
-
- <!-- int rid -->
- <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
- <generator class="org.splat.kernel.IDGenerator"/>
- </id>
-
-
- <!-- Set<Attribute> attributes -->
- <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Attribute" />
- </set>
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Abstract root class of persistent objects supporting dynamic attributes.<br/>
- * Dynamic attributes are instances of concrete subclasses of Attribute that are assigned to Any objects at run time.
- * The attributes of a given Any object must all be of different types.
- *
- * @see Attribute
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.hibernate.Session;
-import org.splat.som.Database;
-
-
-public abstract class Any extends Persistent {
-
- private Set<Attribute> attributes;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor.
- protected Any () {
- }
-// Initialization constructors
- protected Any (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// --------------------------------------
- super(oprop);
- attributes = new HashSet<Attribute>();
- }
- protected Any (Attribute... field) {
-// ----------------------------------
- attributes = new HashSet<Attribute>();
- for (int i=0; i<field.length; i++) {
- if (field[i] == null) continue; // Happen when newing an Any object without property
- if (field[i].getFrom().equals(this)) attributes.add(field[i]);
- }
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Attribute getAttribute (Class<? extends Attribute> type) {
-// ---------------------------------------------------------------
- for (Iterator<Attribute> i=attributes.iterator(); i.hasNext(); ) {
- Attribute field = i.next();
- if (field.getClass().equals(type)) return field;
- }
- return null;
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected boolean removeAttribute (Attribute field) {
-// ---------------------------------------------------
- for (Iterator<Attribute> i=attributes.iterator(); i.hasNext(); ) {
- if (!i.next().equals(field)) continue;
- i.remove();
- if (this.isSaved()) Database.getSession().update(this);
- return true;
- }
- return false;
- }
-
- protected boolean setAttribute (Attribute field) {
-// ------------------------------------------------
- Class<?> type = field.getClass();
- Session session = Database.getSession();
-
- if (!field.getFrom().equals(this)) return false;
- for (Iterator<Attribute> i=attributes.iterator(); i.hasNext(); ) {
- if (!i.next().getClass().equals(type)) continue;
- i.remove();
- break;
- }
- attributes.add(field);
- if (this.isSaved()) {
- if (!field.isSaved()) session.save(field);
- session.update(this);
- } // Else, when saving this, Hibernate will propagate the operation
- return true;
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the Attribute class hierarchy.
- - The attribute hierarchy is mapped to a single table using a String discriminator.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.Attribute" abstract="true" table="attribute">
-
- <!-- int rid -->
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
- <discriminator column="type" type="string"/>
-
- <!-- Any owner -->
- <many-to-one name="owner" column="owner" access="field" not-null="true" />
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @see Any
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-
-public abstract class Attribute extends Persistent {
-
- protected Any owner;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor.
- protected Attribute () {
- }
-// Initialization constructor
- protected Attribute (Any from) {
-// ------------------------------
- this.owner = from;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Persistent getFrom () {
-// ----------------------------
- return owner;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-import org.hibernate.jdbc.Work;
-import org.apache.log4j.Logger;
-
-
-public abstract class Database {
-
-// private static String CONFIG_FILE = "/hibernate.cfg.xml";
- private static SessionFactory mySessionFactory = null;
- protected static IDPool myIDpool = null;
-
- protected class CreateTables implements Work {
-// -----------------------------------------------
- protected Statement request;
-
- public void execute(Connection connex) throws SQLException
- {
- request = connex.createStatement();
-
-// Last identifier of Any objects
- String create = "CREATE TABLE `any` (" +
- "`rid` int(10) UNSIGNED NOT NULL," +
- "`version` tinytext NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Relation from entities
- create = "CREATE TABLE `relation` (" +
- "`rid` int(10) UNSIGNED NOT NULL," +
- "`name` tinytext NOT NULL," +
- "`owner` int(10) NOT NULL," +
- "`refer` int(10) NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Attribute objects
- create = "CREATE TABLE `attribute` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`type` tinytext NOT NULL," +
- "`owner` int(10) NOT NULL," +
- "`value` int(10) NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Java String objects
- create = "CREATE TABLE `text` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`value` longtext NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// User and role objects
- create = "CREATE TABLE `user` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`username` varchar(32) NOT NULL," +
- "`password` varchar(32)," +
- "`first` tinytext NOT NULL," +
- "`last` tinytext NOT NULL," +
- "`display` tinytext," +
- "`email` tinytext," +
- "`organid` tinytext," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
- create = "CREATE TABLE `role` (" +
- "`username` varchar(32) NOT NULL," +
- "`role` varchar(32) NOT NULL," +
- "PRIMARY KEY (`username`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
- }
- }
-
- protected final static Logger logger = Logger.getLogger(Database.class);
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public static Session getSession () {
-// -----------------------------------
- return getInstance().getCurrentSession();
- }
-
- public static void close () {
-// ---------------------------
- if (mySessionFactory != null) mySessionFactory.close();
- mySessionFactory = null;
- }
-
- public static IDPool getIDPool () {
-// ---------------------------------
- if (myIDpool == null) myIDpool = new IDPool(getSession());
- return myIDpool;
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected String getSchemaVersion () {
-// ------------------------------------
- return getIDPool().getSchemaVersion();
- }
-
- protected void setIDPoolSize (int size) {
-// ---------------------------------------
- IDPool.setPoolSize(size);
- }
-
- protected void setSchemaVersion (String version) {
-// ------------------------------------------------
- myIDpool = new IDPool(version);
- getSession().save(myIDpool);
- }
-
-// ==============================================================================================================================
-// Private services
-// ==============================================================================================================================
-
- private static SessionFactory getInstance () {
-// --------------------------------------------
- if (mySessionFactory == null) {
- org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration();
- try {
- cfg.configure(); // The configuration file (hibernate.cfg.xml)) is supposed to be on the classpath
- mySessionFactory = cfg.buildSessionFactory();
- }
- catch (Exception error) {
- logger.fatal("Could not initialize the Hibernate configuration, reason:", error);
- }
- }
- return mySessionFactory;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Date;
-import java.util.Properties;
-
-import javax.activation.DataHandler;
-import javax.activation.DataSource;
-import javax.activation.FileDataSource;
-import javax.mail.BodyPart;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import org.apache.log4j.Logger;
-
-
-public class Do {
-
- public static boolean containsIllicitCharacter (String name) {
-// ------------------------------------------------------------
- char parse[] = name.toCharArray();
-
- for (int i=0; i<parse.length; i++) {
- int k = java.lang.Character.getType(parse[i]);
- if (k == java.lang.Character.DECIMAL_DIGIT_NUMBER) continue;
- if (k == java.lang.Character.LOWERCASE_LETTER) continue;
- if (k == java.lang.Character.UPPERCASE_LETTER) continue;
- if (k == java.lang.Character.SPACE_SEPARATOR) continue;
- if (k == java.lang.Character.END_PUNCTUATION) continue;
- if (k == java.lang.Character.DASH_PUNCTUATION) continue;
- if (parse[i] == '\'') continue;
- if (parse[i] == '_') continue;
- if (parse[i] == '&') continue;
- if (parse[i] == '.') continue;
- return true;
- }
- return false;
- }
-
- public static void copy (File fromFile, File toFile) throws IOException {
-// ----------------------------------------------------
- if (!fromFile.exists()) throw new IOException("ERROR File copy: no such '" + fromFile.getName() + "' source file.");
- if (!fromFile.isFile()) throw new IOException("Error File copy: can't copy directory '" + fromFile.getName() + "'.");
-
- if (toFile.isDirectory()) toFile = new File(toFile, fromFile.getName());
- if (toFile.exists()) throw new IOException("ERROR File copy: file " + toFile.getName() + " already exist.");
- else {
- String parent = toFile.getParent();
- if (parent == null) throw new IOException("ERROR File copy: destination directory not defined.");
- File dir = new File(parent);
- if (!dir.exists()) throw new IOException("ERROR File copy: destination directory " + parent + " doesn't exist.");
- }
- FileInputStream from = null;
- FileOutputStream to = null;
- try {
- from = new FileInputStream(fromFile);
- to = new FileOutputStream(toFile);
- byte[] buffer = new byte[4096];
- int bytesRead;
-
- while ((bytesRead = from.read(buffer)) != -1) to.write(buffer, 0, bytesRead); // write
-
- from.close();
- to.close();
- }
- catch (IOException e) {
- throw new IOException();
- }
- }
-
- public static boolean sendMail (User to, String subject, String message, File attachement, Properties mprop) {
-// ------------------------------------------------------------------------------------------------------------
- if (mprop.getProperty("mail.smtp.host") == null) return false;
- if (mprop.getProperty("mail.pop3.host") == null) return false;
- if (mprop.getProperty("mail.from") == null) return false;
-
- Session mail = Session.getInstance(mprop, null);
- Logger log = Logger.getLogger(Do.class);
- try {
- log.info("Preparation of mail to " + to.toString());
-
- MimeMessage msg = new MimeMessage(mail);
- msg.setFrom(); // Address defined in properties at mail.from
- msg.setRecipients(Message.RecipientType.TO, to.getMailAddress());
- msg.setSubject(subject);
-
- BodyPart msgBody = new MimeBodyPart();
- msgBody.setText(message);
-
- Multipart multipart = new MimeMultipart();
- multipart.addBodyPart(msgBody);
-
- if (attachement != null) {
- String attachname = attachement.getCanonicalPath();
-
- msgBody = new MimeBodyPart();
- DataSource attachment = new FileDataSource(attachname);
- msgBody.setDataHandler(new DataHandler(attachment));
- msgBody.setFileName(attachname);
- multipart.addBodyPart(msgBody);
- }
- msg.setContent(multipart);
- msg.setSentDate(new Date());
-
- Transport.send(msg);
- log.info("sent.");
-
- } catch (MessagingException mex) {
- log.error("Send mail failed, reason " + mex);
- return false;
-
- } catch (IOException mex) {
- log.error("Send mail failed, reason " + mex);
- return false;
- }
- return true;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class DuplicatePropertyException extends Exception {
-
- private static final long serialVersionUID = 189342004009382158L;
-
- public DuplicatePropertyException (String message) {
- super(message);
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the root abstract class supporting relations.
- -
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.Entity" abstract="true">
-
- <!-- int rid -->
- <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
- <generator class="org.splat.kernel.IDGenerator"/>
- </id>
-
-
- <!-- Set<Attribute> attributes -->
- <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Attribute" />
- </set>
-
- <!-- Set<Relation> relations -->
- <set name="relations" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Relation" />
- </set>
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Abstract root class of persistent objects supporting relations to other persistent objects.<br/>
- * Relations are instances of concrete subclasses of Relation that are assigned to Entity objects at run time.<br/>
- * <br/>
- * Entity objects also support dynamic attributes provided by the Any class.
- *
- * @see Relation
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-
-import org.hibernate.Session;
-
-
-public abstract class Entity extends Any {
-
- private Set<Relation> relations;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected Entity () {
- }
-// Initialization constructor
- protected Entity (ObjectProperties prop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// ----------------------------------------
- super(prop);
- relations = new HashSet<Relation>();
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Relation getFirstRelation (Class<? extends Relation> type) {
-// -----------------------------------------------------------------
- for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
- Relation link = i.next();
- if (link.getClass().equals(type)) return link;
- }
- return null;
- }
-
- public List<Relation> getRelations (Class<? extends Relation> type) {
-// -------------------------------------------------------------------
- List<Relation> result = new Vector<Relation>();
-
- for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
- Relation link = i.next();
- if (link.getClass().equals(type)) result.add(link);
- }
- return result;
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected Set<Relation> getAllRelations () {
-// ------------------------------------------
- return relations;
- }
-
- protected Relation addRelation (Relation link) {
-// ----------------------------------------------
- Session session = Database.getSession();
-
- session.save(link);
- relations.add(link);
- session.update(this);
-
- if (link.isBidirectional()) {
- Entity to = (Entity)link.getTo(); // Bidirectional relation are necessarily between entities
-
- link = link.getReverse();
- session.save(link);
-// if (to.relations == null) to.relations = new HashSet<Relation>();
- to.relations.add(link);
- session.update(to);
- }
- return link;
- }
-
- protected void removeRelation (Class<? extends Relation> type, Persistent to) {
-// -----------------------------------------------------------------------------
- for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
- Relation link = i.next();
- if (!link.getClass().equals(type)) continue;
- if (!link.getTo().equals(to)) continue;
- i.remove();
- if (this.isSaved()) Database.getSession().update(this);
- return;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-import org.hibernate.usertype.EnhancedUserType;
-import org.hibernate.usertype.ParameterizedType;
-
-
-public class GenericEnumType implements EnhancedUserType, ParameterizedType {
-
- @SuppressWarnings("unchecked")
- private Class<Enum> enumClass;
-
- @SuppressWarnings("unchecked")
- public void setParameterValues (Properties parameters) {
-// ------------------------------------------------------
- String enumClassName = parameters.getProperty("enumClassName");
- try {
- enumClass = (Class<Enum>) Class.forName(enumClassName);
- }
- catch (ClassNotFoundException cnfe) {
- throw new HibernateException("Enum class not found", cnfe);
- }
- }
-
- public Object assemble (Serializable cached, Object owner) throws HibernateException {
-// ----------------------------------------------------------
- return cached;
- }
-
- public Object deepCopy (Object value) throws HibernateException {
-// -------------------------------------
- return value;
- }
-
- @SuppressWarnings("unchecked")
- public Serializable disassemble (Object value) throws HibernateException {
-// ----------------------------------------------
- return (Enum) value;
- }
-
- public boolean equals (Object x, Object y) throws HibernateException {
-// ------------------------------------------
- return x==y;
- }
-
- public int hashCode (Object x) throws HibernateException {
-// ------------------------------
- return x.hashCode();
- }
-
- public boolean isMutable () {
-// ---------------------------
- return false;
- }
-
- @SuppressWarnings("unchecked")
- public Object nullSafeGet (ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
-// ----------------------------------------------------------------------
- String name = rs.getString( names[0] );
- return rs.wasNull() ? null : Enum.valueOf(enumClass, name);
- }
-
- @SuppressWarnings("unchecked")
- public void nullSafeSet (PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-// -----------------------------------------------------------------------
- if (value==null) {
- st.setNull(index, Types.VARCHAR);
- }
- else {
- st.setString( index, ( (Enum) value ).name() );
- }
- }
-
- public Object replace (Object original, Object target, Object owner) throws HibernateException {
-// --------------------------------------------------------------------
- return original;
- }
-
- @SuppressWarnings("unchecked")
- public Class returnedClass () {
-// -----------------------------
- return enumClass;
- }
-
- public int[] sqlTypes () {
-// ------------------------
- return new int[] { Types.VARCHAR };
- }
-
- @SuppressWarnings("unchecked")
- public Object fromXMLString (String xmlValue) {
-// ---------------------------------------------
- return Enum.valueOf(enumClass, xmlValue);
- }
-
- @SuppressWarnings("unchecked")
- public String objectToSQLString (Object value) {
-// ----------------------------------------------
- return '\'' + ( (Enum) value ).name() + '\'';
- }
-
- @SuppressWarnings("unchecked")
- public String toXMLString (Object value) {
-// ----------------------------------------
- return ( (Enum) value ).name();
- }
-
-
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Class generating the persistent identifier of all objects instance of a subclass of Any.<br/>
- * The implementation of this generator is optimized basing on IDPool.
- *
- * @see IDPool
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.IdentifierGenerator;
-
-
-public class IDGenerator implements IdentifierGenerator {
-
- public Serializable generate (SessionImplementor session, Object any) throws HibernateException {
-// ---------------------------------------------------------------------
- return Database.getIDPool().getNextID();
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.IDPool" table="any">
-
-
- <id name="lastid" column="rid" access="field">
- <generator class="assigned"/>
- </id>
-
- <property name="version" column="version" access="field" not-null="true" />
-
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Optimized generator of persistent identifiers.<br/>
- * This generator minimizes the database hits by grouping a bunch of identifiers in memory and only hitting the database
- * when the in-memory value group is exhausted.
- * Only one IDPool object held by the Database class is created during a session.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import org.hibernate.Session;
-import org.hibernate.jdbc.Work;
-
-
-public class IDPool {
-
-// Persistent fields
- private Integer lastid; // Last generated ID
- private String version; // Version of the database schema
-
-// Transient fields
- private int remaining; // Remaining available ID held in this pool
- private static int poolsize = 1; // No pool by default
-
- private class LoadNewIDs implements Work {
-// -----------------------------------------
- public void execute(Connection connex) throws SQLException
- {
- Statement request = connex.createStatement();
- ResultSet result = request.executeQuery("SELECT MAX(rid) AS lastid FROM any");
- StringBuffer command = new StringBuffer("UPDATE any SET rid=");
-
- result.first();
- lastid = result.getInt("lastid");
-
- command.append(lastid + poolsize).append(" WHERE rid=").append(lastid);
- request.execute(command.toString());
-
- remaining = poolsize;
- }
- }
- private class LoadLastID implements Work {
-// -----------------------------------------
- public void execute(Connection connex) throws SQLException
- {
- Statement request = connex.createStatement();
- ResultSet result = request.executeQuery("SELECT MAX(rid) AS lastid FROM any");
- StringBuffer command = new StringBuffer("SELECT version FROM any WHERE rid=");
-
- result.first();
- lastid = result.getInt("lastid");
-
- command.append(lastid);
- result = request.executeQuery(command.toString());
- result.first();
- version = result.getString("version");
- remaining = 0;
- }
- }
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
- protected IDPool () {
- }
-/**
- * Constructor called only once, when initializing the database.
- *
- * @param version the version of the constructed database schema.
- */
- protected IDPool (String version) {
-// ---------------------------------
- this.lastid = 0; //TODO: Get the current last ID if a previous version exists
- this.version = version;
- this.remaining = 0;
- }
-/**
- * Constructor called at start of every database session.
- *
- * @param base the started database session
- */
- protected IDPool (Session base) {
-// -------------------------------
- base.doWork( new LoadLastID() );
- }
-
-// ==============================================================================================================================
-// Protected member functions
-// ==============================================================================================================================
-
- protected Integer getNextID () {
-// ------------------------------
- if (remaining <= 0) Database.getSession().doWork( new LoadNewIDs() );
- lastid += 1;
- remaining -= 1;
- return lastid;
- }
-
- protected String getSchemaVersion () {
-// ------------------------------------
- return version;
- }
-
- protected static void setPoolSize (int size) {
-// --------------------------------------------
- if (size > 1) poolsize = size;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class InvalidPropertyException extends Exception {
-
- private static final long serialVersionUID = -3988379180445723963L;
-
- public InvalidPropertyException (String message) {
- super(message);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class MismatchException extends Exception {
-
- private static final long serialVersionUID = 366699682058153984L;
-
- public MismatchException () {
- }
- public MismatchException (String message) {
- super(message);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class MissedPropertyException extends Exception {
-
- private static final long serialVersionUID = -4459708372517969441L;
-
- public MissedPropertyException (String message) {
- super(message);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class MultiplyDefinedException extends Exception {
-
- private static final long serialVersionUID = 3551033092059904168L;
-
- public MultiplyDefinedException () {
- }
- public MultiplyDefinedException (String message) {
- super(message);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Interface implemented by the User class for allowing the application to manipulate lists of user names mixing
- * real users and generic users such as Author of something or Responsible of that.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-
-public interface Name {
-
- public int getIndex ();
- public String toString ();
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class NotApplicableException extends Exception {
-
- private static final long serialVersionUID = -6255758696740565804L;
-
- public NotApplicableException (String message) {
- super(message);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Common interface of intermediate properties objects used for constructing persistent objects supporting the API Design Pattern
- * provided by this package.
- * This interface mainly provides a frame for checking the validity of arguments used by persistent object constructors.
- * The validity check is implemented in classes inheriting from the Persistent.Properties abstract class through the checkValidity
- * member function defined in this interface - see class User included in this package for an example of use.
- *
- * @see Persistent
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-public interface ObjectProperties {
-
-/**
- * Checks the mutual compatibility of arguments previously set in the properties object.
- * The validity of each individual argument is supposed to be check first in the setter function of the argument.
- *
- * @throws MissedPropertyException
- * @throws InvalidPropertyException
- * @throws MultiplyDefinedException
- */ public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException;
-
- /**
- * Disables the validity check.
- * The validity check is by default enabled when constructing an properties object.
- */ public void disableCheck ();
-
- /**
- * Returns true if the validity check is enabled.
- */ public boolean mustBeChecked ();
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the primary key common to all Persistent objects.
- -
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.Persistent" abstract="true">
-
-
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Base implementation of the API Design Pattern of objects which persistence is based on Hibernate.<br/>
- * This Design Pattern supports the following features:
- * <ul>
- * <li>Flexible API for constructing objects from many variable arguments</li>
- * <li>Impossible to leave persistent objects in inconsistent state, even temporarily, during their construction</li>
- * <li>Same Object Oriented API for constructing and selecting objects from the database</li>
- * <li>Centralized validity check of arguments</li>
- * </ul>
- * The API is based on intermediate properties objects used for collecting arguments and checking their validity.
- * These properties objects are passed to persistent object constructors and database select functions for execution.
- * For example, as based on this Design Pattern, a User object could be created that way:
- * <pre>
- * User.Properties args = new User.Properties();
- * User user = new User( args.setUsername("mypseudo").setMailAddress("me@provider.domain") );
- * </pre>
- * Classes implementing this Design Pattern must inherit from Persistent and implement their Properties class as a nested
- * subclass of Persistent.Properties.<br/>
- * <br/>
- * Naturally, as usual with Hibernate, any class can be persistent (you don't need to inherit from Persistent for being
- * persistent). Inheriting from Persistent is only a matter of enabling the API supported by the above Design Pattern.
- *
- * @see ObjectProperties
- * @see Persistent.Properties
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-
-public abstract class Persistent {
-
- private int rid; // Primary key of persistent objects
-
- protected abstract static class Properties implements ObjectProperties {
-// ----------------------------------------------------------------------
- private boolean tobechecked = true; // Property validity check flag
-
- public void disableCheck () {
- tobechecked = false;
- }
- public boolean mustBeChecked () {
- return tobechecked;
- }
- public void clear () {
- tobechecked = true;
- }
- }
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-/**
- * Database fetch constructor.
- */
- protected Persistent () {
-// -----------------------
- rid = 0; // Set when loading the object
- }
-
-/**
- * Checks the mutual compatibility of arguments previously set in the given properties object, if the validity check is enabled.
- * As this validity depends on concrete classes, the check is delegated to subclasses of the given Persistent.Properties.
- */
- protected Persistent (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// ---------------------------------------------
- if (oprop.mustBeChecked()) oprop.checkValidity(); // Throws one of the above exception if not valid
- rid = 0; // Set when saving the object
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean equals(Object entity) {
-// ------------------------------------
- if (entity == null) return false;
- if (entity.getClass().equals(this.getClass())) {
- Persistent object = (Persistent)entity;
- int he = object.getIndex(); // getIndex() is supposed fetching the index if not yet done
- int me = this.getIndex(); // getIndex() is supposed fetching the index if not yet done
- if (me*he != 0) return (he == me);
- if (me+he == 0) return (this == object);
- }
- return false;
- }
-
-/**
- * Returns the Persistent ID of this object. The PID is set when saving this object. It is unique in the scope of the class
- * of this object only.
- *
- * @return the PID of this, or 0 if this is not saved.
- * @see isSaved()
- */
- public int getIndex () {
-// ----------------------
- return rid;
- }
-
- public int hashCode () {
-// ----------------------
- return toString().hashCode();
- }
-
-/**
- * Returns true if this object is saved.
- *
- * @return true if this is saved.
- * @see getIndex()
- */
- public boolean isSaved () {
-// -------------------------
- return (getIndex() != 0); // getIndex() is supposed fetching the index if not yet done
- }
-
-/**
- * Return a string representing uniquely this object.
- *
- * @return the unique string representation of this object.
- */
- public String toString () {
-// -------------------------
- int oid = getIndex(); // getIndex() is supposed fetching the index if not yet done
- if (oid == 0) oid = super.hashCode(); //WARNING: Must not call super.toString() as it goes back here (this.toString())
- return new StringBuffer("object ").append(getClass().getName()).append("@").append(oid).toString();
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Map;
-
-import javax.security.auth.*;
-import javax.security.auth.callback.*;
-import javax.security.auth.login.*;
-import javax.security.auth.spi.*;
-
-import org.apache.log4j.Logger;
-
-
-public class RealmLoginModule implements LoginModule {
-
-// Initial state
- private Subject subject;
- private CallbackHandler callbackHandler;
-// private Map sharedState;
-// private Map options;
-
-// Authentication status
- private boolean succeeded = false;
- private boolean commit = false;
-
-// Principal
- private User identity = null;
-
- private Logger logger = null;
-
-// ==============================================================================================================================
-// Constructor
-// ==============================================================================================================================
-
- public void initialize(Subject user, CallbackHandler handler, Map<String, ?> state, Map<String, ?> opts) {
-// --------------------------------------------------------------------------------------------------------
- subject = user;
- callbackHandler = handler;
-// sharedState = state;
-// options = opts;
-// debug = "true".equalsIgnoreCase((String)options.get("debug"));
- logger = Logger.getLogger(Database.class);
- }
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public boolean login() throws LoginException {
-// ----------------------
- try {
-// Ask for username password
- Callback[] callbacks = new Callback[2];
- callbacks[0] = new NameCallback("username");
- callbacks[1] = new PasswordCallback("password", false);
-
- callbackHandler.handle(callbacks);
-
- String username = ((NameCallback)callbacks[0]).getName();
- String password = null;
- char[] entered = ((PasswordCallback)callbacks[1]).getPassword();
- if (entered != null) {
- password = new String(entered);
- ((PasswordCallback)callbacks[1]).clearPassword();
- }
-
-// Authentication
- User found = UserDirectory.selectUser(username, password);
- if (found != null) {
- identity = found;
- succeeded = true;
- Calendar today = java.util.Calendar.getInstance();
- Date datime = today.getTime();
- logger.info("RKV:Connection of " + identity.toString() + " " + datime.toString() + ".");
- return true;
- } else {
- identity = null;
- succeeded = false;
- found = UserDirectory.selectUser(username);
- String reason = "password";
- if (found == null) reason = "username";
- logger.info("Connection attempt as " + username + ".");
- throw new FailedLoginException(reason);
- }
- }
- catch (java.io.IOException ioe) {
- throw new LoginException(ioe.toString());
- }
- catch (UnsupportedCallbackException uce) {
- throw new LoginException("Error: " + uce.getCallback().toString() +
- " not available to garner authentication information" +
- " from the user");
- }
- }
-
- public boolean commit() throws LoginException {
-// -----------------------
- if (!succeeded) return false;
-
- if (!subject.getPrincipals().contains(identity)) subject.getPrincipals().add(identity);
- identity = null;
- commit = true;
- return true;
- }
-
- public boolean abort() throws LoginException {
-// ----------------------
- if (!succeeded) {
- return false;
- } else
- if (succeeded && !commit) {
- identity = null;
- succeeded = false;
- } else {
- logout();
- }
- return true;
- }
-
- public boolean logout() throws LoginException {
-// -----------------------
- subject.getPrincipals().remove(identity);
- identity = null;
- succeeded = false;
- commit = false; // To be validated
- return true;
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the Relation class hierarchy.
- - The entire hierarchy is mapped to one single table using a String discriminator.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.Relation" abstract="true" table="relation">
-
- <!-- int rid -->
- <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
- <generator class="org.splat.kernel.IDGenerator"/>
- </id>
- <discriminator column="name" type="string"/>
-
- <!-- Set<Attribute> attributes -->
- <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Attribute" />
- </set>
-
- <!-- Entity owner -->
- <many-to-one name="owner" column="owner" access="field" not-null="true" />
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Base implementation of relations between entities.<br/>
- * A relation makes a typed link from an entity to any kind persistent object. The relations are typed by subclasses of this
- * abstract class which define the actual object referenced by the relation.<br/>
- * This Relation base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses
- * by:
- * <ul>
- * <li>overriding the isBidirectional() and getReverseClass() methods,</li>
- * <li>creating the reverse relation in constructors.</li>
- * </ul>
- * Relation objects also support dynamic attributes provided by the Any class.
- *
- * @see Entity
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Iterator;
-
-import org.hibernate.Session;
-
-
-public abstract class Relation extends Any {
-
-// Persistent fields
- protected Entity owner; // Study or Document
-
-// Transient field
- protected Relation reverse;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected Relation () {
-// ---------------------
- reverse = null;
- }
-// Initialization constructor
- protected Relation (Entity from) {
-// --------------------------------
- super((Attribute)null); // For building the collection of attributes
- this.owner = from;
- this.reverse = null; // Initialized by subclasses
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Entity getFrom () {
-// ------------------------
- return owner;
- }
-
- public Relation getReverse () {
-// -----------------------------
- if (!this.isBidirectional() || reverse != null) return reverse;
-
- Class<? extends Relation> type = this.getReverseClass();
- Entity to = (Entity)this.getTo(); // Bidirectional relations are necessarily between Entities
-
- for (Iterator<Relation> i=to.getAllRelations().iterator(); i.hasNext(); ) {
- Relation asked = i.next();
- if (!asked.getClass().equals(type)) continue;
- if (!asked.getTo().equals(owner)) continue;
- reverse = asked;
- reverse.reverse = this; // For benefiting from this execution
- return reverse;
- }
- return null;
- }
-
- public Class<? extends Relation> getReverseClass () {
-// ---------------------------------------------------
- return null;
- }
-
- public boolean isBidirectional () {
-// ---------------------------------
- return false;
- }
-
-/**
- * Moves this relation from its current owner entity to the given one.
- *
- * @param nowner the document to which this relation is moved
- * */
- public void moveTo (Entity nowner) {
-// ----------------------------------
- Session session = Database.getSession();
-
- this.owner = nowner;
- nowner.getAllRelations().add(this);
-// myold.getAllRelations().remove(this); Harmful as it leads to remove this relation from the database (!?)
- session.update(this);
- session.update(nowner);
-
- if (this.isBidirectional()) {
- Relation link = this.getReverse();
- link.setTo(nowner);
- session.update(link);
- }
- }
-
-// ==============================================================================================================================
-// Abstract functions
-// ==============================================================================================================================
-
- public abstract Persistent getTo ();
- protected abstract void setTo (Persistent to); // For the need of the moveTo() method
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Class of objects representing the role of users.
- * A role is named by an application-dependent string (reason why role names are not defined by an enumeration).
- * A user may have several roles, user roles being stored into the database as a list of role names separated by a comma.
- *
- * @see User
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Vector;
-
-
-public class Role {
-
- private String username;
- private String role;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected Role () {
- }
-// Initialization constructor
- protected Role (String username, String role) {
-// ---------------------------------------------
- this.username = username;
- this.role = role;
- }
-
-// ==============================================================================================================================
-// Protected member functions
-// ==============================================================================================================================
-
- protected void addRole (String role) {
-// ------------------------------------
- this.role = this.role + "," + role;
- }
-
- protected Role[] toArray () {
-// ---------------------------
- String[] name = role.split(",");
- Vector<Role> role = new Vector<Role>();
-
- for (int i=0; i<name.length; i++) role.add(new Role(username, name[i]));
- return role.toArray(new Role[name.length]);
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-// In functions bellow, the role is supposed having previously been extracted as an array.
-
- public String getName () {
-// ------------------------
- return role;
- }
-
- public boolean is (String name) {
-// -------------------------------
- return this.role.equals(name);
- }
-
- public boolean isSame (Role other) {
-// ----------------------------------
- return this.role.equals(other.role);
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of persistent Java String.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.kernel.Text" table="text" lazy="false">
-
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
- <property name="value" column="value" access="field" not-null="true" />
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Class implementing Hibernate-based persistent Java String.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.som.Database;
-
-
-public class Text extends Persistent {
-
- private String value;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor.
- protected Text () {
- }
-// Initialization constructor
- public Text (String value) {
-// --------------------------
- this.value = value;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public String getValue () {
-// -------------------------
- return value;
- }
-
- public void setValue (String value) {
-// -----------------------------------
- this.value = value;
- if (this.isSaved()) Database.getSession().update(this);
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <subclass name="org.splat.kernel.TextAttribute" extends="org.splat.kernel.Attribute" discriminator-value="text">
-
- <many-to-one name="mytext" column="value" access="field" cascade="all" not-null="true" />
-
- </subclass>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-
-public abstract class TextAttribute extends Attribute {
-
- private Text mytext;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor.
- protected TextAttribute () {
- }
-// Initialization constructor
- protected TextAttribute (Any from, Text value) {
-// ----------------------------------------------
- super(from);
- mytext = value;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public String getValue () {
-// -------------------------
- return mytext.getValue();
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected void setValue (String value) {
-// --------------------------------------
- mytext.setValue(value);
- if (this.isSaved()) Database.getSession().update(this);
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the User class and its corresponding Role definition.
- - User and Role are associated by a one-to-one association on the username User foreign key.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
-<!-- Class User
- -->
- <class name="org.splat.kernel.User" table="user" lazy="false">
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
- <natural-id>
- <property name="username" column="username" access="field" />
- <many-to-one name="role" column="username" insert="false" update="false" unique="true" cascade="save-update" access="field" />
- <property name="email" column="email" access="field" />
- </natural-id>
- <property name="password" column="password" access="field" />
- <property name="first" column="first" access="field" not-null="true" />
- <property name="last" column="last" access="field" not-null="true" />
- <property name="display" column="display" access="field" />
- <property name="organid" column="organid" access="field" />
- </class>
-
-<!-- Class Role
- -->
- <class name="org.splat.kernel.Role" table="role" lazy="false">
- <id name="username" column="username" access="field">
- <generator class="assigned"/>
- </id>
- <property name="role" column="role" access="field" not-null="true" />
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.security.Principal;
-
-import org.splat.kernel.Persistent;
-
-
-public class User extends Persistent implements Principal, Name {
-
-// Persistent fields
- @SuppressWarnings("unused")
- private String password; // Property without getter function
-
- private String username; // Unique in the user directory
- private String first;
- private String last;
- private String display; // Optional
- private Role role; // Roles as list (as stored into the database)
- private String email;
- private String organid;
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private String username = null;
- private String password = null;;
- private String first = null;
- private String last = null;
- private String display = null;
- private Role role = null;
- private String email = null;
- private String organid = null;
-
-// - Public services
-
- public void clear () {
- super.clear();
- username = null;
- password = null;;
- first = null;
- last = null;
- display = null;
- role = null;
- email = null;
- organid = null;
- }
- public String getOrganizationName () {
- return organid;
- }
- public String getPassword () {
- return password;
- }
- public String getUsername () {
- return username;
- }
-// - Property setters
-
- public Properties addRole (String role) throws InvalidPropertyException
- {
- if (role.length() == 0) throw new InvalidPropertyException("role");
- if (this.role == null) {
- this.role = new Role(username, role);
- } else {
- Role[] curole = this.role.toArray();
- for (int i=0; i<curole.length; i++) if (curole[i].is(role)) return this;
- this.role.addRole(role);
- }
- return this;
- }
- public Properties setDisplayName (String display) throws InvalidPropertyException
- {
- if (display.length() == 0) throw new InvalidPropertyException("displayname");
- this.display = display;
- return this;
- }
- public Properties setFirstName (String first) throws InvalidPropertyException
- {
- if (first.length() == 0) throw new InvalidPropertyException("firstname");
- this.first = first;
- return this;
- }
- public Properties setMailAddress (String address) throws InvalidPropertyException
- {
- String[] term = address.split("@"); // Must be of the form x@y
- if (term.length != 2) throw new InvalidPropertyException("address");
- term = term[1].split("\\x2E"); // Must be of the form x@y.z
- if (term.length != 2) throw new InvalidPropertyException("address");
- this.email = address;
- return this;
- }
- public Properties setName (String last) throws InvalidPropertyException
- {
- if (last.length() == 0) throw new InvalidPropertyException("lastname");
- this.last = last;
- return this;
- }
- public Properties setOrganizationName (String organization) throws InvalidPropertyException
- {
- if (organization.length() == 0) throw new InvalidPropertyException("organization");
- this.organid = organization;
- return this;
- }
- public Properties setPassword (String password) throws InvalidPropertyException
- {
- if (password != null) {
- if (password.length() < 1) throw new InvalidPropertyException("password");
- this.password = String.valueOf(password.hashCode());
- }
- return this;
- }
- public Properties setUsername (String username) throws InvalidPropertyException
- {
- if (username.length() == 0) throw new InvalidPropertyException("username");
- this.username = username;
- return this;
- }
-// - Global validity check
-
- public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (username == null) throw new MissedPropertyException("username");
- if (first == null) throw new MissedPropertyException("firstname");
- if (last == null) throw new MissedPropertyException("lastname");
- if (role == null) throw new MissedPropertyException("role");
- if (email == null) throw new MissedPropertyException("email");
-//TODO: Check if username exists
- }
- }
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected User () {
-// --------------
- }
-// Anonymous user supposed not to be saved
- public User (String name) {
-// -------------------------
- username = null;
- password = null;
- first = null;
- last = null;
- display = name;
- role = null;
- email = null;
- organid = null;
- }
-// New user
- public User (Properties uprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// ------------------------------
- super(uprop); // Throws one of the above exception if not valid
- this.username = uprop.username;
- this.password = uprop.password;
- this.first = uprop.first;
- this.last = uprop.last;
- this.display = uprop.display;
- this.role = uprop.role;
- this.email = uprop.email;
- this.organid = uprop.organid;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean equals (Object item) {
-// -----------------------------------
- if (item == null) return false;
- if (item instanceof String) {
- return this.username.equals((String)item); // Usernames are unique
- }
- else if (item instanceof User) {
- User given = (User)item;
- if (isSaved()) return (this.getIndex() == given.getIndex());
- else return (this.username.equals(given.username)); // Usernames are unique
- } else {
- return false;
- }
- }
-
- public String getDisplayName () {
-// -------------------------------
- if (display == null) return last + " " + first;
- else return display;
- }
-
- public String getFirstName () {
-// -----------------------------
- return first;
- }
-
- public String getMailAddress () {
-// -------------------------------
- return email;
- }
-
- public String getName () {
-// ------------------------
- return last;
- }
-
- public String getOrganizationName () {
-// ------------------------------------
- return organid;
- }
-
- public String getRoleNames () {
-// -----------------------------
- return role.getName();
- }
-
- public Role[] getRoles () {
-// -------------------------
- return role.toArray();
- }
-
- public String getUsername () {
-// ----------------------------
- return username;
- }
-
- public String toString () {
-// -------------------------
- return last + " " + first;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- * Very minimal implementation of the user directory of a company department.<br/>
- * This directory can include members of the department, the two level hierarchy of these members (their n+1 and n+2 managers),
- * and all customers of the department.<br/>
- * The department hierarchy is defined through a hard-coded combination of user role and organization names (see the getManagerOf
- * function of this class). It is useful for implementing an application workflow requiring such informmation (the n+1 and n+2
- * managers are usually involved in the validation process).<br/>
- * <br/>
- * When needed, a full implementation of the company organization can be adjoin to this class by using user organization names
- * as reference to departments into this organization. In this context, the function getManagerOf(user) of this class will be
- * ineffective (it will return null).
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.IOException;
-import java.io.File;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.hibernate.Session;
-import org.splat.som.Database;
-import org.w3c.dom.Node;
-import org.apache.log4j.Logger;
-
-
-public class UserDirectory {
-
- final static Logger logger = Logger.getLogger(UserDirectory.class);
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public static User createUser (User.Properties uprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
-// -----------------------------------------------------
- User nuser = new User(uprop);
- Session session = Database.getSession();
- session.save(nuser);
-
- return nuser;
- }
-
- @SuppressWarnings("unchecked") // For the casting List<String>
- public static Set<User> importUsers (File xfile) throws XMLException, MismatchException, RuntimeException {
-// ------------------------------------------------
- String[] name = xfile.getName().split("\\x2E"); // Split by '.' (period) character
- String fext = name[name.length-1];
- Session session = Database.getSession();
-
- if (!fext.equals("xml")) throw new MismatchException("filetype");
- try {
- DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
- DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
- org.w3c.dom.Document inDoc = dBuilder.parse(xfile);
- String xtag = inDoc.getDocumentElement().getNodeName();
- if (!xtag.equals("users")) throw new MismatchException("filetype");
- org.w3c.dom.NodeList ulist = inDoc.getElementsByTagName("user");
-
- List<String> result = (List<String>)session.createSQLQuery("SELECT * FROM user").addScalar("username").list();
- HashSet<String> members = new HashSet<String>();
- HashSet<User> imported = new HashSet<User>();
- for (Iterator<String> i=result.iterator(); i.hasNext();) members.add(i.next());
-
- for (int i=0; i<ulist.getLength(); i++) {
- HashMap<String, Node> row = XDOM.getNamedChildNodes(ulist.item(i));
- User.Properties uprop = new User.Properties();
-
-// Mandatory properties
- String uname = row.get("username").getTextContent();
- if (members.contains(uname)) continue; // This user already exists
- uprop.setUsername(uname)
- .setFirstName(row.get("first").getTextContent())
- .setName(row.get("last").getTextContent())
- .setMailAddress(row.get("mail").getTextContent())
- .addRole(row.get("role").getTextContent()); // Add all roles at a time
-
-// Optional properties
- org.w3c.dom.Node node = row.get("password");
- if (node != null) {
- uprop.setPassword(node.getTextContent());
- }
- node = row.get("display");
- if (node != null) {
- uprop.setDisplayName(node.getTextContent());
- }
- node = row.get("organization");
- if (node != null) {
- uprop.setOrganizationName(node.getTextContent());
- }
-// Addition of the user
- uprop.disableCheck(); // Existent user already checked above
- User newser = new User(uprop);
- session.save(newser);
- imported.add(newser);
- }
- return imported;
- }
- catch (IOException error) {
- throw new XMLException("XML users file not found");
- }
- catch (ParserConfigurationException e) {
- throw new XMLException("XML Organization parser not accessible");
- }
- catch (Exception e) {
- throw new XMLException("XML users file not valid");
- }
- }
-
-/**
- * Returns the manager of the given user.
- * This function is effective providing that users are defined according to the following conventions:
- * <ul>
- * <li>One user is assigned in the organization as Nx1 (n+1 manager of members of the organization)</li>
- * <li>Another user is assigned in the organization as Nx2 (n+2 manager of members of the organization)</li>
- * </ul>
- * If such users do not exit, null is returned.
- *
- * @param user the user whose manager is get
- * @return the manager of the given user, if defined
- */
- public static User getManagerOf (User user) {
-// -------------------------------------------
- User result = null;
- String orgname = user.getOrganizationName();
-
- if (orgname.equals("Nx2")) return result;
- if (orgname.equals("Nx1")) orgname = "Nx2";
- else {
- if (user.getRoleNames().equals("customer")) return result;
- orgname = "Nx1";
- }
- try {
- User.Properties uprop = new User.Properties();
- List<User> ulist = UserDirectory.selectUsersWhere(uprop.setOrganizationName(orgname));
- return ulist.get(0); // n+1 and n+2 managers are unique
- }
- catch (Exception e) {
- return null;
- }
- }
-
- @SuppressWarnings("unchecked") // For the casting List<User>
- public static List<User> selectAllUsers () {
-// ------------------------------------------
- String query = "from User order by last asc, first asc";
- return (List<User>)Database.getSession().createQuery(query).list();
- }
-
- public static User selectUser (String username) {
-// -----------------------------------------------
- StringBuffer query = new StringBuffer("from User where username='").append(username).append("'");
- return (User)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static User selectUser (String username, String password) {
-// ----------------------------------------------------------------
-//WARNING: For not encoding the password here, we better call a selectUsersWhere(User.Properties),
-// but this requires a getPassword in User.Properties nested class.
- StringBuffer query = new StringBuffer("from User where username='").append(username).append("' and password");
- if (password == null) query = query.append(" is null");
- else query = query.append("='").append(String.valueOf(password.hashCode())).append("'");
-
- return (User)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static User selectUser (int index) {
-// -----------------------------------------
- StringBuffer query = new StringBuffer("from User where rid='").append(index).append("'");
- return (User)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- @SuppressWarnings("unchecked")
- public static List<User> selectUsersWhere (User.Properties... uprop) {
-// --------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from User");
- String separator = " where (";
- String value;
-
- for (int i=0; i<uprop.length; i++) {
-
- value = uprop[i].getOrganizationName();
- if (value != null) {
- query = query.append(separator).append(" organid='").append(value).append("'");
-// separator = " and";
- }
- separator = ") or (";
- }
- query.append(")");
- return (List<User>)Database.getSession().createQuery(query.toString()).list();
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.apache.log4j.Logger;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.util.HashMap;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-
-public class XDOM {
-
- private final static Logger logger = Logger.getLogger(XDOM.class);
-
- public static org.w3c.dom.Document createDocument (String name) {
-// ---------------------------------------------------------------
- DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
- try {
- DocumentBuilder dbuilder = dfactory.newDocumentBuilder();
- org.w3c.dom.Document document = dbuilder.newDocument();
-
- Element root = document.createElement(name);
- document.appendChild(root);
-
- return document;
- }
- catch (Exception error) {
- logger.error("Could not create document " + name + ", reason:", error);
- return null;
- }
- }
-
- public static Node getChildNode (String name, Node from) {
-// --------------------------------------------------------
- NodeList nlist = from.getChildNodes();
- for (int i=0; i<nlist.getLength(); i++) {
- Node cnode = nlist.item(i);
- if (cnode.getNodeName().equals(name)) return cnode;
- }
- return null;
- }
-
- public static HashMap<String,Node> getNamedChildNodes (Node node) {
-// -----------------------------------------------------------------
- HashMap<String,Node> result = new HashMap<String,Node>();
- NodeList nlist = node.getChildNodes();
- for (int i=0; i<nlist.getLength(); i++) {
- node = nlist.item(i);
- String name = node.getNodeName();
- if (name.startsWith("#")) continue;
- result.put(name, node);
- }
- return result;
- }
-
- public static boolean saveDocument (File xmlOutputFile, org.w3c.dom.Document doc) {
-// ---------------------------------------------------------------------------------
-// Open output stream where XML Document will be saved
-// File xmlOutputFile = new File(fileName);
- FileOutputStream fos;
- Transformer transformer;
- try {
- fos = new FileOutputStream(xmlOutputFile);
- }
- catch (FileNotFoundException error) {
- logger.error("Could not open the " + xmlOutputFile.getName() + " file, reason:", error);
- return false;
- }
-// Use a Transformer for output
- TransformerFactory transformerFactory = TransformerFactory.newInstance();
- try {
- transformer = transformerFactory.newTransformer();
- }
- catch (TransformerConfigurationException error) {
- logger.error("Transformer configuration error, reason:", error);
- return false;
- }
- DOMSource source = new DOMSource(doc);
- StreamResult result = new StreamResult(fos);
-// Transform source into result will do save
- try {
- transformer.transform(source, result);
- }
- catch (TransformerException error) {
- logger.error("Error during XML transformation, reason:", error);
- }
- return true;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.kernel;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public class XMLException extends Exception {
-
- private static final long serialVersionUID = -4807111035943839090L;
-
- public XMLException () {
- }
- public XMLException (String message) {
- super(message);
- }
-}
\ No newline at end of file
import java.util.HashMap;
import java.util.Vector;
-import org.splat.kernel.XDOM;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
--- /dev/null
+package org.splat.manox;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.apache.log4j.Logger;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.HashMap;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+public class XDOM {
+
+ private final static Logger logger = Logger.getLogger(XDOM.class);
+
+ public static org.w3c.dom.Document createDocument (String name) {
+// ---------------------------------------------------------------
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder dbuilder = dfactory.newDocumentBuilder();
+ org.w3c.dom.Document document = dbuilder.newDocument();
+
+ Element root = document.createElement(name);
+ document.appendChild(root);
+
+ return document;
+ }
+ catch (Exception error) {
+ logger.error("Could not create document " + name + ", reason:", error);
+ return null;
+ }
+ }
+
+ public static Node getChildNode (String name, Node from) {
+// --------------------------------------------------------
+ NodeList nlist = from.getChildNodes();
+ for (int i=0; i<nlist.getLength(); i++) {
+ Node cnode = nlist.item(i);
+ if (cnode.getNodeName().equals(name)) return cnode;
+ }
+ return null;
+ }
+
+ public static HashMap<String,Node> getNamedChildNodes (Node node) {
+// -----------------------------------------------------------------
+ HashMap<String,Node> result = new HashMap<String,Node>();
+ NodeList nlist = node.getChildNodes();
+ for (int i=0; i<nlist.getLength(); i++) {
+ node = nlist.item(i);
+ String name = node.getNodeName();
+ if (name.startsWith("#")) continue;
+ result.put(name, node);
+ }
+ return result;
+ }
+
+ public static boolean saveDocument (File xmlOutputFile, org.w3c.dom.Document doc) {
+// ---------------------------------------------------------------------------------
+// Open output stream where XML Document will be saved
+// File xmlOutputFile = new File(fileName);
+ FileOutputStream fos;
+ Transformer transformer;
+ try {
+ fos = new FileOutputStream(xmlOutputFile);
+ }
+ catch (FileNotFoundException error) {
+ logger.error("Could not open the " + xmlOutputFile.getName() + " file, reason:", error);
+ return false;
+ }
+// Use a Transformer for output
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ try {
+ transformer = transformerFactory.newTransformer();
+ }
+ catch (TransformerConfigurationException error) {
+ logger.error("Transformer configuration error, reason:", error);
+ return false;
+ }
+ DOMSource source = new DOMSource(doc);
+ StreamResult result = new StreamResult(fos);
+// Transform source into result will do save
+ try {
+ transformer.transform(source, result);
+ }
+ catch (TransformerException error) {
+ logger.error("Error during XML transformation, reason:", error);
+ }
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.manox;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class XMLException extends Exception {
+
+ private static final long serialVersionUID = -4807111035943839090L;
+
+ public XMLException () {
+ }
+ public XMLException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Base implementation of actor relations such as Contributor, Reviewer and Approver.
- * ActorRelation objects are attached to Documents for defining those who HAVE CONTRIBUTED to these documents,
- * while instances of subclasses of ActorRelation are attached to Studies for setting those who CAN CONTRIBUTE to given document types.</br>
- * </br>
- * Depending on the actual relation object, the value of the actor relation has different meaning:
- * <ul>
- * <li>The description of ActorRelation objects defines the type of contributions (Contributor, Reviewer, Approver...)</li>
- * <li>The description of instances of subclasses of ActorRelation defines the type of acting documents</li>
- * </ul>
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-import org.splat.kernel.User;
-
-
-public abstract class ActorRelation extends Relation {
-
- private User refer;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected ActorRelation () {
- }
-// ActorRelation subclasses constructor
- protected ActorRelation (Study from, User to) {
-// ---------------------------------------------
- super(from);
- this.refer = to;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public User getTo () {
-// --------------------
- return refer;
- }
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (User)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.splat.kernel.Role;
-import org.splat.kernel.User;
-
-
-public class ApplicationRights {
-
- private User user;
- private Set<String> roles;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
- public ApplicationRights (User user) { // Warning: user may be null
-// ------------------------------------
- this.roles = new HashSet<String>();
- this.user = user;
- if (user != null) {
- Role[] role = user.getRoles();
- for (int i=0; i<role.length; i++) {
- String iam = role[i].getName();
- roles.add(iam);
- }
- }
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean canCreateStudy () {
-// --------------------------------
- if (user != null) {
- String position = user.getOrganizationName();
- if (position != null && position.equals("Nx2")) return false;
- }
- return roles.contains(Profile.manager.toString());
- }
-
- public boolean canContributeToStudy () {
-// --------------------------------------
- if (user != null) {
- String position = user.getOrganizationName();
- if (position != null && (position.equals("Nx1") || position.equals("Nx2"))) return false;
- }
- return (roles.contains(Profile.manager.toString()) || roles.contains(Profile.studengineer.toString()));
- }
-
- public boolean canValidate () {
-// -----------------------------
- return roles.contains(Profile.manager.toString());
- }
-
- public boolean canManageKnowledges () {
-// -------------------------------------
- if (user != null) {
- String position = user.getOrganizationName();
- if (position != null && position.equals("Nx2")) return false;
- }
- return roles.contains(Profile.knowledgineer.toString());
- }
-
- public boolean canManageDatabase () {
-// -----------------------------------
- if (user != null) {
- String position = user.getOrganizationName();
- if (position != null && position.equals("Nx2")) return false;
- }
- return roles.contains(Profile.sysadmin.toString());
- }
-
-// ==============================================================================================================================
-// Getters
-// ==============================================================================================================================
-
- public User getUser () {
-// ----------------------
- return user; // May be null
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the Attribute concrete subclasses.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
-<!-- Description attribute
- -->
- <subclass name="org.splat.som.DescriptionAttribute" extends="org.splat.kernel.TextAttribute" discriminator-value="description">
- <!-- no extra property -->
- </subclass>
-
-<!-- Comment attribute
- -->
- <subclass name="org.splat.som.CommentAttribute" extends="org.splat.kernel.TextAttribute" discriminator-value="comment">
- <!-- no extra property -->
- </subclass>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Attribute class of type Comment.<br/>
- * A comment is made of any text up to 65 thousand characters.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Text;
-import org.splat.kernel.TextAttribute;
-
-
-public class CommentAttribute extends TextAttribute {
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor.
- protected CommentAttribute () {
- }
-/**
- * Constructs a comment attached to a time stamp.
- *
- * @param from the time stamp to which this comment is attached.
- * @param value the text of this comment
- */
- protected CommentAttribute (Timestamp from, String value) {
-// ---------------------------------------------------------
- super(from, new Text(value));
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.User;
-
-
-public class ContributorRelation extends ActorRelation {
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected ContributorRelation () {
- }
-// Initialization constructor
- protected ContributorRelation (Study from, User to) {
-// --------------------------------------------------
- super(from, to);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-
-
-public class ConvertsRelation extends Relation {
-
-// Persistent field
- private File refer;
-
-// Transient fields
- private boolean got; // For optimizing getDescription()
- private String description; // Null if this is not described
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected ConvertsRelation () {
-// -----------------------------
- got = false;
- description = null;
- }
-// Initialization constructors
- protected ConvertsRelation (Document from, File to) {
-// ---------------------------------------------------
- super(from);
- this.refer = to;
- this.got = true;
- this.description = null; // Conversion not described
- }
- protected ConvertsRelation (Document from, File to, String description) {
-// -----------------------------------------------------------------------
- super(from);
- this.refer = to;
- this.got = true;
- this.description = description; // May be null
- if (description != null) this.setAttribute( new DescriptionAttribute(this, description) );
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public String getDescription () {
-// -------------------------------
- if (!got) {
- DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
- if (field != null) description = field.getValue();
- got = true; // Don't need to be modified later as set and remove attribute functions are private to this class
- }
- return description; // May be null
- }
-
- public File getTo () {
-// --------------------
- return refer;
- }
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (File)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.Query;
-import org.hibernate.Session;
-import org.hibernate.jdbc.Work;
-import org.apache.log4j.Logger;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanFilter;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.FilterClause;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.SortField;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TermsFilter;
-import org.apache.lucene.search.TopFieldDocs;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-
-import org.splat.kernel.User;
-import org.splat.kernel.UserDirectory;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-
-
-public class Database extends org.splat.kernel.Database {
-
- private int uplevel = 0; // Level of database upgrade
- private String basepath = null; // Path of the root directory of repository
-
- private static Database my = null; // Singleton instance
-
- protected class CreateTables extends org.splat.kernel.Database.CreateTables {
-// ---------------------------------------------------------------------------
- public void execute(Connection connex) throws SQLException
- {
- super.execute(connex);
-
-// Study Entity
- String create = "CREATE TABLE `study` (" +
- "`rid` int(10) UNSIGNED NOT NULL," +
- "`sid` tinytext NOT NULL," +
- "`title` tinytext NOT NULL," +
- "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED', 'TEMPLATE') NOT NULL default 'inWORK'," +
- "`area` enum('PRIVATE','PUBLIC','REFERENCE') NOT NULL default 'PRIVATE'," +
- "`manager` int(10) NOT NULL," +
- "`version` tinytext NOT NULL," +
- "`docount` int(10) UNSIGNED NOT NULL," +
- "`history` int(10) UNSIGNED NOT NULL," +
- "`credate` date NOT NULL," +
- "`lasdate` date NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Scenario Entity
- create = "CREATE TABLE `scenario` (" +
- "`rid` int(10) UNSIGNED NOT NULL," +
- "`sid` int(10) UNSIGNED NOT NULL," +
- "`owner` int(10) NOT NULL," +
- "`scendex` int(3) NOT NULL," +
- "`title` tinytext NOT NULL," +
- "`manager` int(10) NOT NULL," +
- "`cuser` int(10)," +
- "`credate` date NOT NULL," +
- "`lasdate` date NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Document Entity and document tag (Publication)
- create = "CREATE TABLE `document` (" +
- "`rid` int(10) UNSIGNED NOT NULL," +
- "`did` tinytext NOT NULL," +
- "`type` int(10) NOT NULL," +
- "`step` int(10) NOT NULL," +
- "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED','EXTERN') NOT NULL default 'inWORK'," +
- "`name` tinytext NOT NULL," +
- "`author` int(10) NOT NULL," +
- "`version` tinytext," +
- "`countag` int(10) UNSIGNED NOT NULL," +
- "`history` int(10) NOT NULL," +
- "`myfile` int(10) NOT NULL," +
- "`lasdate` date NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
- create = "CREATE TABLE `doctag` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`doc` int(10) NOT NULL," +
- "`owner` int(10) NOT NULL," +
- "`isnew` char(1) NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-// Document types
- create = "CREATE TABLE `doctype` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`name` tinytext NOT NULL," +
- "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
- "`step` tinytext NOT NULL," +
- "`result` tinytext," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-// Document types dependencies
- create = "CREATE TABLE `docuse` (" +
- "`owner` int(10) NOT NULL," +
- "`rid` int(10) NOT NULL" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// ValidationCycle related object
- create = "CREATE TABLE `cycle` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`type` int(10) NOT NULL," +
- "`publisher` int(10)," +
- "`reviewer` int(10)," +
- "`approver` int(10)," +
- "`signatory` int(10)," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Timestamp related object
- create = "CREATE TABLE `stamp` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`type` enum('PROMOTION','REVIEW','APPROVAL','ACCEPTANCE','DISTRIBUTION','REFUSAL') NOT NULL," +
- "`author` int(10) NOT NULL," +
- "`date` datetime NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// KnowledgeElements objects
- create = "CREATE TABLE `knowelm` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`type` int(10) NOT NULL," +
- "`owner` int(10) NOT NULL," +
- "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED') NOT NULL default 'inDRAFT'," +
- "`title` tinytext NOT NULL," +
- "`value` text NOT NULL," +
- "`author` int(10) NOT NULL," +
- "`date` date NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-// KnowledgeElement types
- create = "CREATE TABLE `knowtype` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`name` tinytext NOT NULL," +
- "`state` enum('inWORK','inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// SimulationContext objects
- create = "CREATE TABLE `contelm` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`type` int(10) NOT NULL," +
- "`step` int(10) NOT NULL," +
- "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
- "`value` text NOT NULL," +
- "`counter` int(10) UNSIGNED NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-// SimulationContext types
- create = "CREATE TABLE `contype` (" +
- "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
- "`name` tinytext NOT NULL," +
- "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
- "`step` int(10) NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Many-to-many association between ProjectElement (Study and Scenario) and SimulationContext
- create = "CREATE TABLE `projext` (" +
- "`owner` int(10) NOT NULL," +
- "`ordex` int(10) NOT NULL," +
- "`rid` int(10) NOT NULL" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// File objects
- create = "CREATE TABLE `file` (" +
- "`rid` int(10) UNSIGNED NOT NULL," +
- "`format` tinytext NOT NULL," +
- "`path` tinytext NOT NULL," +
- "`date` date NOT NULL," +
- "PRIMARY KEY (`rid`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
-
-// Reference objects
- create = "CREATE TABLE `refid` (" +
- "`cycle` int(10) NOT NULL," +
- "`base` int(10) NOT NULL," +
- "PRIMARY KEY (`cycle`)" +
- ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
- request.execute(create);
- }
- }
- protected class CheckVersion implements Work {
-// --------------------------------------------
- public void execute(Connection connex) throws SQLException
- {
- DatabaseMetaData dbmdata = connex.getMetaData();
- String dbname = "simer"; //TODO: Get the name from meta-data
- ResultSet table;
-
- table = dbmdata.getTables(dbname, null, "study", null);
- if (table.next()) return;
- uplevel = -1; // Database not initialized
- }
- }
-
- protected final static Logger logger = org.splat.kernel.Database.logger;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
- public static Database getMe () {
-// -------------------------------
- if (my == null) try {
- my = new Database();
- }
- catch (Exception error) {
- logger.fatal("Could not access the database, reason:", error);
- }
- return my;
- }
- private Database () {
-// -------------------
- Database.getSession().doWork(new CheckVersion());
- this.setIDPoolSize(4); // Average number of generated IDs when creating a study and versioning a document
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean isInitialized () {
-// -------------------------------
- return (uplevel >= 0);
- }
-
- public void initialize () throws IOException, SQLException {
-// -------------------------
- logger.info("Creation of the database.");
-
-// Creation of the Lucene index
- Index.create(); // May throw IOException if the index repository is improperly configured
-
-// Creation of the SIMER SQL tables
- Session session = Database.getSession();
- session.doWork(new CreateTables()); // May throw SQLException if the SIMER database does not exist
- session.flush();
-
-// Population of the database with customized data
- this.populate();
-
- session.flush();
- uplevel = 0; // The database is now up-to-date
- }
-
-// ==============================================================================================================================
-// Protected member functions
-// ==============================================================================================================================
-
- protected void configure (Properties reprop) {
-// --------------------------------------------
- basepath = reprop.getProperty("repository");
- }
-
- protected void populate () {
-// --------------------------
- try {
-// Initialization of the schema version
- this.setSchemaVersion("D0.3"); //TODO: Get the version name from the configuration file
-
-// Creation of the default system administrator
-//TODO: Get the username password from the Hibernate configuration
- User.Properties uprop = new User.Properties();
- uprop.setUsername("simer")
- .setPassword("admin")
- .setName("Simulation")
- .setFirstName("Manager")
- .setDisplayName("label.sysadmin")
- .addRole("sysadmin")
- .setMailAddress("noreply@salome-platform.org");
- uprop.disableCheck();
- UserDirectory.createUser(uprop);
- }
- catch (Exception e) {
-// Let's continue, hoping the best...
- }
- ProjectSettings.getMe().initialize(); // Populates the database with all necessary stuff
- }
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public static Study createStudy (Study.Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
-// --------------------------------------------------------
- Study study = new Study(sprop);
-
- study.buildReference();
- Database.getSession().save(study);
- try {
- Index lucin = getIndex();
- lucin.add(study);
- }
- catch (IOException error) {
- logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
-// Continue and try to index later
- }
- return study;
- }
-
- public static void indexStudy (Study study) {
-// -------------------------------------------
- try {
- Study.Properties sprop = new Study.Properties();
- List<Proxy> index = Database.selectStudiesWhere(sprop.setReference(study.getReference()));
-
- if (index.size() != 0) return; // The given study is already indexed
-
- Index lucin = getIndex();
- Scenario[] scenes = study.getScenarii();
-
- lucin.add(study);
- if (study.getProgressState() != ProgressState.inWORK) for (int i=0; i<scenes.length; i++) {
- List<KnowledgeElement> list = scenes[i].getAllKnowledgeElements();
- for (Iterator<KnowledgeElement> j=list.iterator(); j.hasNext(); ) {
- lucin.add(j.next());
- }
- }
- }
- catch (Exception error) {
- logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
- }
- }
-
- public static Index getIndex () throws IOException {
-// -------------------------------
- Index lucin = new Index();
- if ( !lucin.exists() ) Index.create(); // Happens when re-indexing all studies
- return lucin;
- }
-
- public static File getDownloadDirectory (User user) {
-// ---------------------------------------------------
- StringBuffer path = new StringBuffer(my.basepath).append("downloads/").append(user.getUsername()).append("/");
- return new File(path.toString());
- }
-
- public static File getRepositoryIndexDirectory () {
-// -------------------------------------------------
- return new File(my.basepath + "lucin/");
- }
-
- public static String getRepositoryVaultPath () {
-// --------------------------------------------
- return (my.basepath + "vault/");
- }
-
- public static String getTemplatePath () {
-// ---------------------------------------
- return (my.basepath + "templates/");
- }
-
- public static Document selectDocument (int index) {
-// -------------------------------------------------
- StringBuffer query = new StringBuffer("from Document where rid='").append(index).append("'");
- return (Document)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static Document selectDocument (String refid, String version) {
-// --------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from Document where did='").append(refid).append("' and version='").append(version).append("'");
- return (Document)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static KnowledgeElement selectKnowledgeElement (int index) {
-// -----------------------------------------------------------------
- StringBuffer query = new StringBuffer("from KnowledgeElement where rid='").append(index).append("'");
- KnowledgeElement result = (KnowledgeElement)Database.getSession().createQuery(query.toString()).uniqueResult();
-
- result.getOwnerScenario().getOwnerStudy().loadWorkflow();
- return result;
- }
-
- public static List<Proxy> selectKnowledgeElementsWhere (KnowledgeElement.Properties... kprop) {
-// ---------------------------------------------------------------------------------------------
- List<Proxy> result = new ArrayList<Proxy>();
- int hitsize = 20;
- try {
-
-// Creation of the Lucene query
- File indir = Database.getRepositoryIndexDirectory();
- Directory index = FSDirectory.open(indir);
- IndexSearcher searcher = new IndexSearcher(index, true);
- BooleanQuery fulquery = new BooleanQuery();
-
- for (int i=0; i<kprop.length; i++) {
- BooleanQuery query = new BooleanQuery();
- Term input; // Supposed initialized below at least by the visibility
-
- Visibility area = kprop[i].getVisibility(); // Visibility
- if (area != null) {
- input = new Term("area");
- query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
- }
- ProgressState state = kprop[i].getProgressState(); // State
- if (state != null) {
- input = new Term("state");
- query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
- }
- String refid = kprop[i].getReference(); // Reference
- if (refid != null) {
- input = new Term("ref");
- query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
- }
- KnowledgeElementType type = kprop[i].getType(); // Type
- if (type != null) {
- input = new Term("type");
- query.add(new TermQuery(input.createTerm(type.getName())), BooleanClause.Occur.MUST);
- }
- User manager = kprop[i].getAuthor(); // Author
- if (manager != null) {
- input = new Term("author");
- query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
- }
- User actor = kprop[i].getActor(); // Contributor, Reviewer or Approver of the owner study
- if (actor != null) {
- input = new Term("actor");
- query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
- }
- String title = kprop[i].getTitle(); // Title
- if (title != null) {
- input = new Term("contents");
- BooleanQuery critext = new BooleanQuery();
- String operator = "AND"; // Future user input
- BooleanClause.Occur clause = BooleanClause.Occur.MUST;
- if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
- String[] word = title.split(" ");
- for (int j=0; j<word.length; j++) {
- critext.add(new TermQuery(input.createTerm(word[j])), clause);
- }
- query.add(critext, BooleanClause.Occur.MUST);
- }
- List<SimulationContext> context = kprop[i].getSimulationContexts();
- if (context != null && context.size() > 0) {
- BooleanQuery critext = new BooleanQuery();
- for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
- SimulationContext seltext = j.next();
- input = new Term(String.valueOf(seltext.getType().getIndex()));
- critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
- }
- query.add(critext, BooleanClause.Occur.MUST);
- }
- fulquery.add(query, BooleanClause.Occur.SHOULD);
- }
- if (logger.isInfoEnabled()) {
- logger.info("Searching knowledges by Lucene query \"" + fulquery.toString() + "\".");
- }
-// Creation of the knowledge filter
- BooleanFilter filter = new BooleanFilter();
- TermsFilter select = new TermsFilter();
- Term mytype = new Term("class");
- select.addTerm( mytype.createTerm("KnowledgeElement") );
- filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
-
-// Creation of the sort criteria
- Sort sort = new Sort(new SortField("title", SortField.STRING));
-
-// Search
- TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
-
- if (found.totalHits < 1) return result; // No study found
-
-// Construction of the result list
- ScoreDoc[] hits = found.scoreDocs;
- for (int i=0; i<hits.length; i++) {
- result.add( new Index.ObjectProxy(searcher.doc(hits[i].doc)) );
- }
- searcher.close();
- }
- catch (Exception error) {
- logger.error("Error during Lucene search, reason:", error);
- }
- return result;
- }
-
- public static SimulationContext selectSimulationContext (int index) {
-// -------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContext where rid='").append(index).append("'");
- return (SimulationContext)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static SimulationContext selectSimulationContext (SimulationContextType celt, String value) {
-// --------------------------------------------------------------------------------------------------
- SimulationContext result = null;
- try {
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- List<SimulationContext> clist = selectSimulationContextsWhere(cprop.setType(celt).setValue(value));
- if (!clist.isEmpty()) result = clist.get(0); // Supposed being the most used one if many exist
- }
- catch (InvalidPropertyException error) {
- logger.info("Attempt to select a simulation context \"" + celt.getName() + "\" with an invalid value.");
- }
- return result;
- }
-
- @SuppressWarnings("unchecked")
- public static List<SimulationContext> selectSimulationContextsWhere (SimulationContext.Properties cprop) {
-// --------------------------------------------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContext");
- String separator = " where";
- SimulationContextType celt = cprop.getType();
- String value = cprop.getValue();
- ProgressState state = cprop.getProgressState();
- String order = "";
-
- if (celt != null) { query = query.append(separator).append(" type='").append(celt.getIndex()).append("'");
- separator = " and";
- order = " order by value asc";
- }
- if (value != null ) { query = query.append(separator).append(" value='").append(value).append("'");
- separator = " and";
- }
- if (state != null ) { query = query.append(separator).append(" state='").append(state).append("'");
- if (celt == null) order = " order by type asc";
- }
- query.append(order);
- return (List<SimulationContext>)Database.getSession().createQuery(query.toString()).list();
- }
-
- public static Study selectStudy (int index) {
-// -------------------------------------------
- StringBuffer query = new StringBuffer("from Study where rid='").append(index).append("'");
- Study result = (Study)Database.getSession().createQuery(query.toString()).uniqueResult();
-
- result.loadWorkflow();
- return result;
- }
-
- public static Study selectStudy (String refid) {
-// ----------------------------------------------
- StringBuffer query = new StringBuffer("from Study where sid='").append(refid).append("'");
- Study result = (Study)Database.getSession().createQuery(query.toString()).uniqueResult();
-
- result.loadWorkflow();
- return result;
- }
-
- public static List<Proxy> selectStudiesWhere (Study.Properties... sprop) {
-// ------------------------------------------------------------------------
- List<Proxy> result = new ArrayList<Proxy>();
- int hitsize = 20;
- try {
-
-// Creation of the Lucene query
- File indir = Database.getRepositoryIndexDirectory();
- Directory index = FSDirectory.open(indir);
- IndexSearcher searcher = new IndexSearcher(index, true);
- BooleanQuery fulquery = new BooleanQuery();
-
- for (int i=0; i<sprop.length; i++) {
- BooleanQuery query = new BooleanQuery();
- Term input; // Supposed initialized below at least by the visibility
-
- Visibility area = sprop[i].getVisibility(); // Visibility
- if (area != null) {
- input = new Term("area");
- query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
- }
- ProgressState state = sprop[i].getProgressState(); // State
- if (state != null) {
- input = new Term("state");
- if (state == ProgressState.inPROGRESS) {
- BooleanQuery cristate = new BooleanQuery();
- cristate.add(new TermQuery(input.createTerm("inWORK")), BooleanClause.Occur.SHOULD);
- cristate.add(new TermQuery(input.createTerm("inDRAFT")), BooleanClause.Occur.SHOULD);
- cristate.add(new TermQuery(input.createTerm("inCHECK")), BooleanClause.Occur.SHOULD);
- query.add(cristate, BooleanClause.Occur.MUST);
- } else {
- query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
- }
- }
- String refid = sprop[i].getReference(); // Reference
- if (refid != null) {
- input = new Term("ref");
- query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
- }
- User manager = sprop[i].getManager(); // Author
- if (manager != null) {
- input = new Term("author");
- query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
- }
- User actor = sprop[i].getActor(); // Contributor, Reviewer or Approver
- if (actor != null) {
- input = new Term("actor");
- query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
- }
- String title = sprop[i].getTitle(); // Title
- if (title != null) {
- input = new Term("contents");
- BooleanQuery critext = new BooleanQuery();
- String operator = "AND"; // Future user input
- BooleanClause.Occur clause = BooleanClause.Occur.MUST;
- if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
- String[] word = title.split(" ");
- for (int j=0; j<word.length; j++) {
- critext.add(new TermQuery(input.createTerm(word[j])), clause);
- }
- query.add(critext, BooleanClause.Occur.MUST);
- }
- List<SimulationContext> context = sprop[i].getSimulationContexts();
- if (context != null && context.size() > 0) {
- BooleanQuery critext = new BooleanQuery();
- for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
- SimulationContext seltext = j.next();
- input = new Term(String.valueOf(seltext.getType().getIndex()));
- critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
- }
- query.add(critext, BooleanClause.Occur.MUST);
- }
- fulquery.add(query, BooleanClause.Occur.SHOULD);
- }
- if (logger.isInfoEnabled()) {
- logger.info("Searching studies by Lucene query \"" + fulquery.toString() + "\".");
- }
-// Creation of the studies filter
- BooleanFilter filter = new BooleanFilter();
- TermsFilter select = new TermsFilter();
- Term mytype = new Term("class");
- select.addTerm( mytype.createTerm("Study") );
- filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
-
-// Creation of the sort criteria
- Sort sort = new Sort(new SortField("title", SortField.STRING));
-
-// Search
- TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
-
- if (found.totalHits < 1) return result; // No study found
-
-// Construction of the result list
- ScoreDoc[] hits = found.scoreDocs;
- for (int i=0; i<hits.length; i++) {
- result.add( new Index.ObjectProxy(searcher.doc(hits[i].doc)) );
- }
- searcher.close();
- }
- catch (Exception error) {
- logger.error("Error during Lucene search, reason:", error);
- }
- return result;
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected static IDBuilder selectIDBuilder (int cycle) {
-// ------------------------------------------------------
- StringBuffer buffer = new StringBuffer("from IDBuilder where cycle='").append(cycle).append("'");
- String qstring = buffer.toString();
- Query query = Database.getSession().createQuery(qstring);
- IDBuilder result = (IDBuilder)query.uniqueResult();
-
- return result;
- }
-
- protected static IDBuilder selectIDBuilder (Date date) {
-// ------------------------------------------------------
- SimpleDateFormat year = new SimpleDateFormat("yyyy");
- String cycle = year.format(date);
- StringBuffer buffer = new StringBuffer("from IDBuilder where cycle='").append(cycle).append("'");
- String qstring = buffer.toString();
- Query query = Database.getSession().createQuery(qstring);
- IDBuilder result = (IDBuilder)query.uniqueResult();
-
- return result;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Attribute class of type Description.<br/>
- * A description is made of any text up to 65 thousand characters.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Text;
-import org.splat.kernel.TextAttribute;
-
-
-public class DescriptionAttribute extends TextAttribute {
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor.
- protected DescriptionAttribute () {
- }
-/**
- * Constructs the description of a study or a scenario.
- *
- * @param from the study or the scenario to which this description is attached.
- * @param value the text of this description
- */
- protected DescriptionAttribute (ProjectElement from, String value) {
-// ------------------------------------------------------------------
- super(from, new Text(value));
- }
-/**
- * Constructs the description attached to a version relation.
- *
- * @param from the version relation to which this description is attached.
- * @param value the text of this description
- */
- protected DescriptionAttribute (VersionsRelation from, String value) {
-// --------------------------------------------------------------------
- super(from, new Text(value));
- }
- /**
- * Constructs the description attached to a conversion relation.
- *
- * @param from the conversion relation to which this description is attached.
- * @param value the text of this description
- */
- protected DescriptionAttribute (ConvertsRelation from, String value) {
-// --------------------------------------------------------------------
- super(from, new Text(value));
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the Document class and its type information implemented by the DocumentType class.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.Document" table="document" lazy="false">
-
-<!-- Properties inherited from Entity
- -->
- <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
- <generator class="org.splat.kernel.IDGenerator"/>
- </id>
- <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Attribute" />
- </set>
- <set name="relations" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Relation" />
- </set>
-
-<!-- Document properties
- -
- - String did -->
- <property name="did" column="did" access="field" not-null="true" />
-
- <!-- DocumentType type -->
- <many-to-one name="type" column="type" access="field" not-null="true" />
-
- <!-- File myfile -->
- <many-to-one name="myfile" column="myfile" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />
-
- <!-- String name -->
- <property name="name" column="name" access="field" not-null="true" />
-
- <!-- ProgressState state -->
- <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
-
- <!-- int step -->
- <property name="step" column="step" access="field" not-null="true" />
-
- <!-- String version -->
- <property name="version" column="version" access="field" />
-
- <!-- int countag -->
- <property name="countag" column="countag" access="field" not-null="true" />
-
- <!-- int history -->
- <property name="history" column="history" access="field" not-null="true" />
-
- <!-- User author -->
- <many-to-one name="author" column="author" access="field" not-null="true" />
-
- <!-- Date lasdate -->
- <property name="lasdate" column="lasdate" access="field" not-null="true" />
- </class>
-
-<!-- Class DocumentType
- -->
- <class name="org.splat.som.DocumentType" table="doctype" lazy="false">
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
- <property name="name" column="name" access="field" not-null="true" />
- <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
- <property name="step" column="step" access="field" not-null="true" />
- <property name="result" column="result" access="field" />
- <set name="uses" table="docuse" lazy="false" access="field">
- <key column="owner" />
- <many-to-many column="rid" class="org.splat.som.DocumentType" />
- </set>
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.text.DecimalFormat;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import org.hibernate.Hibernate;
-import org.hibernate.Session;
-
-import org.splat.kernel.NotApplicableException;
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.User;
-import org.splat.manox.Reader;
-import org.splat.manox.Toolbox;
-import org.splat.som.ProjectSettings.FileNaming;
-import org.splat.som.Timestamp.ComparatorByDate;
-
-
-public class Document extends Entity {
-
-// Persistent fields
- private DocumentType type; // User expendable types
- private File myfile;
- private String did;
- private int step;
- private ProgressState state;
- private String name;
- private String version;
- private int countag;
- private int history;
- private User author;
- private Date lasdate;
-
-// Transient fields
- public static String suformat = "00"; // Format of the suffix number of document did and file name
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private DocumentType type = null;
- private String did = null; // Only for searching from a given reference
- private ProjectElement owner = null; // Only for constructing a document
- private ProjectSettings.Step step = null;
- private ProgressState state = null;
- private String name = null;
- protected String format = null;
- private String version = null;
- private User author = null;
- protected Date date = null;
- private String summary = null; // Only for versioning a document
- private String path = null; // Only for searching from a given path
-
-// - Public services
-
- public void clear () {
- super.clear();
- type = null;
- did = null;
- owner = null;
- step = null;
- state = null;
- name = null;
- format = null;
- version = null;
- author = null;
- date = null;
- summary = null;
- path = null;
- }
- public Properties copy () {
- Properties copy = new Properties();
- copy.type = this.type;
- copy.did = this.did;
- copy.owner = this.owner;
- copy.step = this.step;
- copy.state = this.state;
- copy.name = this.name;
- copy.format = this.format;
- copy.version = this.version;
- copy.author = this.author;
- copy.date = this.date;
- copy.summary = this.summary;
- copy.path = this.path;
- return copy;
- }
-// - Protected services
-
- protected User getAuthor () {
- return author;
- }
- protected String getDescription () {
- return summary;
- }
- protected String getLocalPath () {
- return path;
- }
- protected String getReference () {
- return did;
- }
- protected ProjectSettings.Step getStep () {
- return step;
- }
- protected DocumentType getType () {
- return type;
- }
-// - Property setters
-
- public Properties setAuthor (User user)
- {
- this.author = user;
- return this;
- }
- public Properties setDate (Date date)
- {
- this.date = date;
- return this;
- }
- public Properties setDescription (String summary) throws InvalidPropertyException
- {
- if (summary.length() == 0) throw new InvalidPropertyException("description");
- this.summary = summary;
- return this;
- }
- protected Properties setDocument (Document base)
- {
- type = base.type;
- step = ProjectSettings.getStep(base.step);
- name = base.name;
- format = base.getFormat();
- state = ProgressState.inWORK; // For incrementing the version number at save time
- version = base.version;
- return this;
- }
- public Properties setExternReference (String ref) throws InvalidPropertyException
- {
- if (ref.length() == 0) throw new InvalidPropertyException("reference");
- if (ref.equals(new Revision().toString())) throw new InvalidPropertyException("reference"); // Internal version number
- this.version = ref;
- return this;
- }
- public Properties setFormat (String format) throws InvalidPropertyException
- {
- if (format.length() == 0) throw new InvalidPropertyException("format");
- this.format = format;
- return this;
- }
-// Required only for passing search arguments
- public Properties setLocalPath (String path) throws InvalidPropertyException
- {
- if (path.length() == 0) throw new InvalidPropertyException("path");
- this.path = path;
- return this;
- }
- public Properties setName (String name) throws InvalidPropertyException
- {
- if (name.length() == 0) throw new InvalidPropertyException("name");
- this.name = name;
- return this;
- }
- protected Properties setOwner (ProjectElement owner)
- {
- this.owner = owner;
- return this;
- }
-// Required only for passing search arguments
- public Properties setReference (String did) throws InvalidPropertyException
- {
- if (did.length() == 0) throw new InvalidPropertyException("reference");
- this.did = did;
- return this;
- }
- public Properties setState (ProgressState state) throws InvalidPropertyException
- {
- if (state == ProgressState.inPROGRESS || state == ProgressState.TEMPLATE) throw new InvalidPropertyException("state"); // Non document states
- this.state = state;
- return this;
- }
- protected Properties setStep (ProjectSettings.Step step)
- {
- this.step = step;
- return this;
- }
- public Properties setType (DocumentType type)
- {
- this.type = type;
- return this;
- }
-// - Global validity check
-
- public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (type == null) throw new MissedPropertyException("type");
- if (owner == null) throw new MissedPropertyException("owner");
- if (step == null) throw new MissedPropertyException("step");
- if (author == null) throw new MissedPropertyException("author");
- if (format == null) throw new MissedPropertyException("format");
- if (owner instanceof Study && !step.appliesTo(Study.class)) throw new InvalidPropertyException("step");
- if (!type.isContentInto(step)) throw new InvalidPropertyException("step");
- if (state != null && state != ProgressState.EXTERN) {
-// inDRAFT, inCHECK or APPROVED + version = imposed version (future use)
-// inWORK + version = base version incremented at save time (used for versioning)
- if (version == null) throw new InvalidPropertyException("state");
- }
- if (version != null) {
- if (state == null) state = ProgressState.EXTERN;
- }
- }
- }
-// Database fetch constructor
- protected Document () {
- }
-// Internal constructor
- protected Document (Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// -------------------------------------
- super(dprop); // Throws one of the above exception if not valid
- myfile = new File(null, dprop.format, dprop.date); // The path is initialized below
- type = dprop.type;
- step = dprop.step.getNumber();
- name = dprop.name;
- version = dprop.version;
- author = dprop.author;
- countag = 0;
- history = 0;
- lasdate = myfile.getDate(); // Today if not defined in the properties
-
- state = dprop.state;
- if (state == null) {
- state = ProgressState.inWORK; // Promoted when saving this document
- version = new Revision().toString();
- }
- Study owner = null;
- if (dprop.owner instanceof Study) owner = (Study)dprop.owner;
- else owner = ((Scenario)dprop.owner).getOwnerStudy();
-
- ProjectSettings.Step step = ProjectSettings.getStep(this.step);
- SimpleDateFormat tostring = new SimpleDateFormat("yyyy");
- String year = tostring.format(owner.getDate());
- if (name == null) { // Newed document
- this.name = "%n"; // Named later at publication
- this.history = -1; // Marks the document as undefined for future assignment
- }
- String filename = generateEncodedName(owner);
- String path;
-
- path = owner.getReference();
- did = new StringBuffer(path).append(".%").append(suformat).toString(); // Document reference
- path = new StringBuffer(year).append("/").append(path).append("/").append(step.getPath()) // File path relative to the repository vault
- .append(filename).append(".").append(myfile.getFormat()) // File name and extension
- .toString();
- myfile.changePath(path);
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public File getAttachedFile (String format) {
-// -------------------------------------------
- List<Relation> exports = getRelations(ConvertsRelation.class);
-
- for (Iterator<Relation> i=exports.iterator(); i.hasNext(); ) {
- File export = (File)i.next().getTo();
- if (export.getFormat().equals(format)) return export;
- }
- return null;
- }
-
- public User getAuthor () {
-// ------------------------
- return author;
- }
-
- public Date getCreationDate () {
-// ------------------------------
- return myfile.getDate();
- }
-
- public Date getLastModificationDate () {
-// --------------------------------------
- return lasdate;
- }
-
- public String getFormat () {
-// --------------------------
- return myfile.getFormat();
- }
-
- public Document getPreviousVersion () {
-// -------------------------------------
- Relation previous = getFirstRelation(VersionsRelation.class);
- if (previous != null) return (Document)previous.getTo();
- else return null;
- }
-
- public ProgressState getProgressState () {
-// ----------------------------------------
- return state;
- }
-
-/**
- * Returns the path where all physical files attached to this document are saved.
- * This path is relative to the vault of the repository and include the file name, without extension, common
- * to all physical files attached to this document.
- *
- * @return the path of the document
- */
- public String getRelativePath () {
-// --------------------------------
- String[] table = myfile.getRelativePath().split("\\x2E");
- StringBuffer path = new StringBuffer(table[0]);
- for (int i=1; i<table.length-1; i++) path.append('.').append(table[i]);
- return path.toString();
- }
-
-/**
- * Returns the global unique reference of this document lineage.
- * The document reference is common to all versions of the document (versioning a document does not change its reference).
- * It is made of the owner study reference suffixed by a document identifier unique in the scope of the study.
- *
- * @return the document reference
- */
- public String getReference () {
-// -----------------------------
- return did;
- }
-
- public java.io.File getSaveDirectory () {
-// ---------------------------------------
- String mypath = Database.getRepositoryVaultPath() + myfile.getRelativePath();
- String[] table = mypath.split("/");
-
-// Cutting the filename
- StringBuffer path = new StringBuffer(table[0]);
- for (int i=1; i<table.length-1; i++) path = path.append("/").append(table[i]);
- return new java.io.File(path.append("/").toString());
- }
-
- public File getSourceFile () {
-// ----------------------------
- return myfile;
- }
-
-/**
- * Returns the stamps such as review and approval attached to this document, if exist.
- * If several stamps exist, they are returned in ascending order of dates.
- *
- * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
- */
- public Timestamp[] getStamps () {
-// -------------------------------
- Vector<Timestamp> stamps = new Vector<Timestamp>();
-
- for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
- Relation link = i.next();
- if (link instanceof StampRelation) stamps.add( ((StampRelation)link).getTo() );
- }
- Timestamp[] result = stamps.toArray( new Timestamp[stamps.size()] );
- ComparatorByDate bydate = new Timestamp.ComparatorByDate();
-
- Arrays.sort(result, bydate);
- return result;
- }
-
-/**
- * Returns the title of this document.
- *
- * @return the document title, or an empty string is this document is undefined.
- * @see #isUndefined()
- */
- public String getTitle () {
-// -------------------------
- if (this.isUndefined()) return "";
- else return name;
- }
-
- public DocumentType getType () {
-// ------------------------------
- return type;
- }
-
-/**
- * Returns the version number of this document.
- * The version number, when exists, is either of the internal form (m.n.s) usable for building a Revision object, or any string
- * in case of external document (document with EXTERN state).<br/>
- * <br/>
- * Note: document slots have a version number equal to "0.0.0".
- *
- * @return the version number of this document, or null if this is EXTERN.
- * @see #isUndefined()
- */
- public String getVersion () {
-// ---------------------------
- return version;
- }
-
-/**
- * Returns true if this document is undefined.
- * An undefined document is a meta-document created for reserving the persistent reference of a new document before saving
- * (or importing) this later into the repository.
- * The working copy of a such document may include this reference.
- *
- * @see #getTitle()
- * @see #getVersion()
- * @see #initialize(Properties)
- */
- public boolean isUndefined () {
-// -----------------------------
- return (history == -1);
- }
-
- public boolean isInto (Step container) {
-// --------------------------------------
- return (step == container.getNumber());
- }
-
- public boolean isPublished () {
-// -----------------------------
- return (countag > 0);
- }
-
- public boolean isShared () {
-// --------------------------
- return (countag + history > 1);
- }
-
- public boolean isVersioned () {
-// -----------------------------
- return (history > 0);
- }
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public static DocumentType createType (DocumentType.Properties tprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
-// ---------------------------------------------------------------------
-//TODO: Check for duplicate definition
- DocumentType type = new DocumentType(tprop);
- Session session = Database.getSession();
- session.save(type);
-
- return type;
- }
-
- public static Properties extractProperties (java.io.File file) {
-// --------------------------------------------------------------
- Properties fprop = new Properties();
- Reader tool = Toolbox.getReader(file);
- String value;
- if (tool != null) try {
- value = tool.extractProperty("title");
- if (value != null) fprop.setName(value);
-
- value = tool.extractProperty("reference");
- if (value != null) fprop.setReference(value);
- }
- catch (Exception e) {
- }
- return fprop;
- }
-
- @SuppressWarnings("unchecked")
- public static List<DocumentType> selectAllTypes () {
-// --------------------------------------------------
- String query = "from DocumentType";
-
- List<DocumentType> types = Database.getSession().createQuery(query).list();
- for (Iterator<DocumentType> i=types.iterator(); i.hasNext();) {
- Hibernate.initialize(i.next()); // Supposed fetching document types
- }
- return types;
- }
-
- @SuppressWarnings("unchecked")
- public static List<DocumentType> selectResultTypes () {
-// -----------------------------------------------------
- String query = "from DocumentType where result is not null order by result asc";
-
- return Database.getSession().createQuery(query).list();
- }
-
- public static DocumentType selectType (String name) {
-// ---------------------------------------------------
- String query = new StringBuffer("from DocumentType where name='").append(name).append("'").toString();
-
- return (DocumentType)Database.getSession().createQuery(query).uniqueResult();
- }
-
- public static DocumentType selectType (int index) {
-// -------------------------------------------------
- String query = new StringBuffer("from DocumentType where rid='").append(index).append("'").toString();
-
- return (DocumentType)Database.getSession().createQuery(query).uniqueResult();
- }
-
- @SuppressWarnings("unchecked")
- public static List<DocumentType> selectTypesOf (ProjectSettings.Step step) {
-// --------------------------------------------------------------------------
- Integer number = step.getNumber();
- String query = new StringBuffer("from DocumentType").append(" where step like '%-").append(number).append("-%'").toString();
-
- List<DocumentType> types = Database.getSession().createQuery(query).list();
- for (Iterator<DocumentType> i=types.iterator(); i.hasNext();) {
- Hibernate.initialize(i.next()); // For fetching document types
- }
- return types;
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected ConvertsRelation attach (String format) {
-// -------------------------------------------------
- return attach(format, null);
- }
-
- protected ConvertsRelation attach (String format, String description) {
-// ---------------------------------------------------------------------
- String path = this.getRelativePath();
- File export = new File(path + "." + format);
- ConvertsRelation attach = new ConvertsRelation(this, export, description);
- Session session = Database.getSession();
-
- session.save(export);
- session.save(attach);
-
- this.addRelation(attach); // Updates this
-
- return attach;
- }
-
- protected boolean buildReferenceFrom (ProjectElement scope, Document lineage) {
-// -----------------------------------------------------------------------------
- if (state != ProgressState.inWORK) return false;
- Study owner = null;
- Scenario context = null;
- if (scope instanceof Study) owner = (Study)scope;
- else {
- context = ((Scenario)scope);
- owner = context.getOwnerStudy();
- }
- did = lineage.did;
- if (context != null && (lineage.isVersioned() || owner.shares(lineage))) {
- version = new Revision(version).setBranch(context.getReference()).toString();
- }
- return true;
- }
-
- protected boolean buildReferenceFrom (Study scope) {
-// --------------------------------------------------
- if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
- DecimalFormat tostring = new DecimalFormat(suformat);
-
- did = did.replace ("%" + suformat, tostring.format(scope.getLastLocalIndex()));
- return true;
- }
-
- protected boolean demote () {
-// ---------------------------
- ValidationStep torem;
-
- if (state == ProgressState.inCHECK) {
- state = ProgressState.inDRAFT;
- torem = ValidationStep.REVIEW;
-// This operation must not change the version number of documents.
-// Consequently, inDRAFT documents may have a minor version number equal to zero.
- } else
- if (state == ProgressState.inDRAFT) {
- state = ProgressState.inWORK;
- torem = ValidationStep.PROMOTION;
- } else {
- return false;
- }
- for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
- Relation link = i.next();
- if (!(link instanceof StampRelation)) continue;
- if (((StampRelation)link).getStampType() != torem) continue;
- i.remove();
- break;
- }
- Database.getSession().update(this);
- return true;
- }
-
-/**
- * Increments the reference count of this document following its publication into a Study step.
- *
- * @see #release()
- */
- protected void hold () {
-// ----------------------
- countag += 1;
- if (this.isSaved()) Database.getSession().update(this);
- }
-
-/**
- * Defines this document.
- *
- * @param dprop the properties of the document
- *
- * @see Step#createDocument(Properties)
- * @see #isUndefined()
- */
- protected void initialize (Properties dprop) throws MissedPropertyException, InvalidPropertyException, NotApplicableException {
-// --------------------------------------------
- if (!this.isUndefined()) throw new NotApplicableException("Cannot initialize an existing Document");
- if (dprop.name == null) throw new MissedPropertyException("name");
- if (dprop.name.length() == 0) throw new InvalidPropertyException("name");
- if (dprop.owner == null) throw new MissedPropertyException("owner");
-// if (dprop.owner instanceof Study && !ProjectSettings.getStep(step).appliesTo(Study.class)) {
-// throw new InvalidPropertyException("step");
-// }
- name = dprop.name;
- myfile.changePath( myfile.getRelativePath().replace("%n", getEncodedRootName((Study)dprop.owner)) );
- if (history == -1) history = 0;
- if (dprop.date == null) {
- Calendar current = Calendar.getInstance();
- lasdate = current.getTime(); // Today
- } else {
- lasdate = dprop.date;
- }
- Database.getSession().update(this);
- }
-
- protected boolean promote (Timestamp stamp) {
-// -------------------------------------------
- ProgressState newstate = null;
-
- if (state == ProgressState.inWORK) {
- newstate = ProgressState.inDRAFT; // Promotion to being reviewed
- } else
- if (state == ProgressState.inDRAFT) {
- newstate = ProgressState.inCHECK; // Promotion to approval
- Revision myvers = new Revision(version);
- if (myvers.isMinor()) {
- version = myvers.incrementAs(newstate).toString();
-//TODO: If my physical file is programatically editable, update its (property) version number
-//ISSUE: What about attached files such as PDF if exist, should we remove them ?
- }
- } else
- if (state == ProgressState.inCHECK) {
- newstate = ProgressState.APPROVED;
- }
- this.state = newstate;
- if (stamp != null) this.addRelation( stamp.getContext() );
- Database.getSession().update(this);
- return true;
- }
-
-/**
- * Decrements the reference count of this document following the removal of a Publication from a Study step.
- *
- * @see #hold()
- */
- protected void release () {
-// -------------------------
- countag -= 1;
- if (this.isSaved()) Database.getSession().update(this);
- }
-
- protected void rename (String title) throws InvalidPropertyException {
-// ------------------------------------
- if (title.length() == 0) throw new InvalidPropertyException("name");
-
- Calendar current = Calendar.getInstance();
- this.name = title;
- this.lasdate = current.getTime(); // Today
- Database.getSession().update(this);
- }
-
- protected void updateAs (Revision newvers) {
-// ------------------------------------------
- version = newvers.setBranch(version).toString(); // Branch names are propagated by the versionning
- ProgressState newstate = ProgressState.inCHECK;
- if (newvers.isMinor()) newstate = ProgressState.inWORK;
- state = null; // Just to tell updateAs(sate) to not increment the version number
- updateAs(newstate);
- }
-
- protected void updateAs (ProgressState state) {
-// ---------------------------------------------
- Document previous = null;
-
-// Set of version number
- if (state == ProgressState.EXTERN) {
- if (this.state != ProgressState.EXTERN) this.version = null; // Strange use-case...
- } else {
- Revision myvers = new Revision(version);
- if (!myvers.isNull()) { // Versionning context
- for (Iterator<Relation> i=getAllRelations().iterator(); i.hasNext();) {
- Relation link = i.next();
- if (!link.getClass().equals(VersionsRelation.class)) continue;
- previous = (Document)link.getTo(); // Versioned document
- break;
- }
- }
- if (this.state != null) myvers.incrementAs(state); // Incrementation if the reversion number is not imposed
- this.version = myvers.toString();
- }
-// Update this document and the previous version, if exit
- Session session = Database.getSession();
- if (previous != null) {
- previous.history += 1;
- session.update(previous);
- }
- this.state = state;
- session.update(this);
- }
-
-// protected void upgrade () {
-// -------------------------
-// if (this.state != ProgressState.inWORK) return;
-//
-// Calendar current = Calendar.getInstance();
-// for (Iterator<Relation> i=getAllRelations().iterator(); i.hasNext();) {
-// Relation link = i.next();
-// if (!link.getClass().equals(UsesRelation.class)) continue;
-//
-// Document used = (Document)link.getTo();
-// if (!used.isVersioned()) continue;
-//TODO: Update the uses relation
-// }
-// this.promote();
-// this.lasdate = current.getTime(); // Today
-// Database.getSession().update(this);
-//
-//TODO: Promote documents using this one
-// }
-
-// ==============================================================================================================================
-// Private services
-// ==============================================================================================================================
-
- private String generateEncodedName (Study scope) {
-// ------------------------------------------------
- StringBuffer encoding = new StringBuffer();
- FileNaming scheme = ProjectSettings.getFileNamingScheme();
- DecimalFormat tostring = new DecimalFormat(suformat);
-
- int number = scope.generateLocalIndex();
-
- if (scheme == FileNaming.encoded) {
- encoding.append(scope.getReference()).append(".").append(tostring.format(number));
- } else { // title and (temporarily) asis
- encoding.append(name).append(".").append(tostring.format(number));
- }
- return encoding.toString();
- }
-
- private String getEncodedRootName (Study scope) {
-// -----------------------------------------------
- FileNaming scheme = ProjectSettings.getFileNamingScheme();
-
- if (scheme == FileNaming.encoded) return scope.getReference();
- else return name;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class providing services for checking the rights related to operations on a given document.
- * These rights are partially driven by the validation cycle associated to documents.
- *
- * @see ValidationCycle
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-//TODO: Review this rights in the following contexts:
-// - Document shared by several scenarios
-// - Document out-dated following a modification of a document it uses
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.splat.kernel.Relation;
-import org.splat.kernel.User;
-
-
-public class DocumentRights {
-
- private User user;
- private Publication operand;
- private ValidationCycle cycle;
- private boolean isauthor; // True if the user is author of the document
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
- public DocumentRights (User user, Publication tag) {
-// --------------------------------------------------
- this.user = user;
- this.operand = tag;
- this.cycle = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
- this.isauthor = operand.value().getAuthor().equals(user);
-//TODO: all contributors of the given document (when supported) must also behave as author
- }
- protected DocumentRights (Publication tag) {
-// ------------------------------------------
- this.user = operand.value().getAuthor();
- this.operand = tag;
- this.cycle = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
- this.isauthor = true; // In order to ignore the author state in the context of any user
-//TODO: all contributors of the given document (when supported) must also behave as author
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
-/**
- * Checks if the user has right to accept the modifications of documents depending on the selected document.
- * This operation applies to out-dated documents following a modification of documents they use.
- * Only the author of the document has such right.
- *
- * @return true if the user has right to accept the modifications of dependencies of the document.
- * @see Publication#accept()
- */
- public boolean canAccept () {
-// ---------------------------
- if (!isauthor) return false;
- return operand.isOutdated();
- }
-
-/**
- * Checks if the user has right to approve the selected document.
- * Only the approver of the type of selected document has such right, providing that the document is candidate for approval and
- * all document dependencies have already been approved.
- *
- * @return true if the user has right to approve the document.
- * @see Publication#approve()
- * @see ValidationCycle
- */
- public boolean canApprove () {
-// ----------------------------
- User approver = cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
-
- if (!user.equals(approver)) return false;
- if (operand.getProgressState() != ProgressState.inCHECK) return false;
-
- List<Relation> use = operand.value().getRelations(UsesRelation.class);
- for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
- Document depend = (Document)i.next().getTo();
- ProgressState state = depend.getProgressState();
- if (state == ProgressState.EXTERN) continue; // External documents do not follow this progress state
- if (state != ProgressState.APPROVED) return false;
- }
- return true;
- }
-
-/**
- * Checks if the user has right to attach a file to the selected document.
- * Both, the author, during the elaboration of the document, and the reviewer of the document, during the review process,
- * have such right.
- *
- * @return true if the user has right to attach a file to the document.
- * @see Publication#attach(String)
- * @see Publication#attach(String, String)
- */
- public boolean canAttach () {
-// ---------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
- ProgressState state = operand.value().getProgressState();
-
- if (state == ProgressState.inWORK) return (isauthor);
- else return (isauthor || user.equals(manager) || user.equals(reviewer));
- }
-
-/**
- * Checks if the user has right to demote the selected document.
- * A document can be demoted providing that it is In-Draft or In-Check and all documents using it have previously been demoted.
- * In-Draft documents can be demoted by default by both, the author of the document and the responsible of study, while
- * documents in approval process can be demoted by their approver only.
- *
- * @return true if the user has right to demote the document.
- * @see #canInvalidate()
- * @see #canPromote()
- * @see Publication#demote()
- * @see ValidationCycle
- */
- public boolean canDemote () {
-// ---------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- User publisher = cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
- User approver = cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
- ProgressState mystate = operand.value().getProgressState();
-
- if (mystate == ProgressState.inDRAFT) {
- if (publisher == null) { if (!isauthor && !user.equals(manager)) return false;
- } else if (!user.equals(publisher)) return false;
- } else
- if (mystate == ProgressState.inCHECK) {
- if (!user.equals(approver)) return false;
- } else return false;
-
- List<Relation> use = operand.value().getRelations(UsedByRelation.class);
- for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
- Document depend = (Document)i.next().getTo();
- ProgressState state = depend.getProgressState();
- if (mystate == ProgressState.inDRAFT && state != ProgressState.inWORK) return false;
- if (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) return false;
- }
- return true;
- }
-
-/**
- * Checks if the user has right to check-out the selected document for editing.
- * In-Work documents can be checked-out by both, the author of the document and the responsible of study, while
- * documents In-Draft can be checked-out by the reviewer only.
- *
- * @return true if the user has right to edit the document.
- */
- public boolean canEdit () {
-// -------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
- ProgressState state = operand.value().getProgressState();
-
-//TODO: Should be restricted by the application if no editor available
- if (state == ProgressState.inWORK) {
- if (isauthor || user.equals(manager)) return true;
- } else
- if (state == ProgressState.inDRAFT) {
- if (user.equals(reviewer)) return true;
- }
- return false;
- }
-
-/**
- * Checks if the user has right to promote the selected document.
- * A document can be promoted providing that it is In-Work and all its dependencies have previously been promoted.
- * By default, both the author of the document and the responsible of study has right to promote such document. Otherwise,
- * only the user involved in the Promotion step of validation cycle of the selected document has such right.
- *
- * @return true if the user has right to promote the document.
- * @see #canDemote()
- * @see Publication#promote()
- * @see ValidationCycle
- */
- public boolean canPromote () {
-// ----------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- User publisher = cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
-
- if (operand.getProgressState() != ProgressState.inWORK) return false;
- if (publisher == null) { if (!isauthor && !user.equals(manager)) return false;
- } else { if (!user.equals(publisher)) return false;
- }
- List<Relation> use = operand.value().getRelations(UsesRelation.class);
- for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
- Document depend = (Document)i.next().getTo();
- ProgressState state = depend.getProgressState();
- if (state == ProgressState.EXTERN) continue; // External documents do not follow this progress state
- if (state == ProgressState.inWORK) return false;
- }
- return true;
- }
-
-/**
- * Checks if the user has right to remove the history of the selected document, if exists.
- * Only the responsible of the study have such right.
- *
- * @return true if the user has right to purge the document.
- */
- public boolean canPurge () {
-// --------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- Document doc = operand.value();
-
- if (!user.equals(manager)) return false;
- if (doc.isShared()) return false;
- if (doc.getFirstRelation(VersionsRelation.class) == null) return false;
- return true;
- }
-
-/**
- * Checks if the user has right to remove the selected document from the study.
- * Both, the author of the document and the responsible of the study, have such right, providing that:
- * - the document is neither in review or in approval process
- * - the document is not used by any other document
- *
- * @return true if the user has right to remove the document.
- * @see Step#removeDocument(Publication)
- */
- public boolean canRemove () {
-// ---------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- ProgressState state = operand.getProgressState();
-
- if (!isauthor && !user.equals(manager)) return false;
- if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
-
- List<Publication> using = operand.getRelations(UsedByRelation.class);
- return (using.size() == 0);
- }
-
-/**
- * Checks if the user has right to rename the selected document.
- * Only the author of the document has such right, providing that the document is neither in review nor in approval process.
- *
- * @return true if the user has right to rename the document.
- * @see Publication#rename(String)
- */
- public boolean canRename () {
-// ---------------------------
- ProgressState state = operand.getProgressState();
-
- if (!isauthor) return false; // In case of external document, the author is the one who has imported the document.
- if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
- return (!operand.value().isShared());
- }
-
-/**
- * Checks if the user has right to replace the source file of the selected document.
- * Both, the author of the document and the responsible of study has such right, providing that the document is neither in review
- * nor in approval process.
- *
- * @return true if the user has right to replace the document.
- */
- public boolean canReplace () {
-// ----------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- ProgressState state = operand.getProgressState();
-
- if (!isauthor && !user.equals(manager)) return false; // Supposed to work also in case of external document.
- if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
- return !operand.value().isShared();
- }
-
-/**
- * Checks if the user has right to validate the selected document.
- * Only the reviewer of the type of selected document has such right, providing that the document is being reviewed and
- * all document dependencies have already been validated.
- *
- * @return true if the user has right to validate the document
- * @see #canUnvalidate()
- * @see Publication#review()
- * @see ValidationCycle
- */
- public boolean canReview () {
-// ---------------------------
- User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
-
- if (!user.equals(reviewer)) return false;
- if (operand.getProgressState() != ProgressState.inDRAFT) return false;
-
- List<Relation> use = operand.value().getRelations(UsesRelation.class);
- for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
- Document depend = (Document)i.next().getTo();
- ProgressState state = depend.getProgressState();
- if (state == ProgressState.EXTERN) continue; // External documents do not follow this progress state
- if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) return false;
- }
- return true;
- }
-
-/**
- * Checks if the user has right to undo the validation operation of the selected document.
- * Both, the author and the reviewer of a validated document, have such right.
- *
- * @return true if the user has right to undo the validation operation
- * @see #canDemote()
- * @see #canReview()
- * @see Publication#invalidate()
- * @see ValidationCycle
- */
- public boolean canInvalidate () {
-// -------------------------------
- User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
- ProgressState mystate = operand.value().getProgressState();
-
- if (mystate != ProgressState.inCHECK) return false;
- if (!isauthor && !user.equals(reviewer)) return false;
-
- List<Relation> use = operand.value().getRelations(UsedByRelation.class);
- for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
- Document depend = (Document)i.next().getTo();
- ProgressState state = depend.getProgressState();
- if (mystate == ProgressState.inDRAFT && state != ProgressState.inWORK) return false;
- if (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) return false;
- }
- return true;
- }
-
-/**
- * Checks if the user has right to version the selected document.
- * In-Work documents can be versioned by both, the author of the document and the responsible of study, while
- * documents In-Draft can be versioned by the reviewer only.
- * Additionally, Approved documents can also be versioned by their author in order to enter in a new modification validation cycle.
- *
- * @return true if the user has right to version the document.
- * @see Step#versionDocument(Publication)
- * @see Step#versionDocument(Publication, Document.Properties)
- * @see Step#versionDocument(Publication, String)
- */
- public boolean canVersion () {
-// ----------------------------
- User manager = operand.getOwnerStudy().getAuthor();
- User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
- ProgressState state = operand.value().getProgressState();
-
- if (state == ProgressState.inWORK) {
- if (isauthor || user.equals(manager)) return true;
- } else
- if (state == ProgressState.inDRAFT) {
- if (user.equals(reviewer)) return true;
- } else
- if (state == ProgressState.APPROVED) {
- if (isauthor) return true;
- }
- return false;
- }
-
-// ==============================================================================================================================
-// Getter
-// ==============================================================================================================================
-
-/**
- * Returns the document subject of checks according to this user rights.
- *
- * @return the document subject of checks.
- */
- public Document getOperand () {
-// -----------------------------
- return operand.value();
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.Persistent;
-
-
-public class DocumentType extends Persistent {
-
-// Persistent fields
- private String name;
- private ProgressState state;
- private String step; // List of (dash separated) steps (numbers) containing this type
- private String result; // Step (number ) having this type as result
- private Set<DocumentType> uses;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private String name = null;
- private String step = null;
- private String result = null;
- private DocumentType[] uses = null;
-
-// - Public services
-
- public void clear () {
- super.clear();
- name = null;
- step = null;
- result = null;
- uses = null;
- }
-// - Setters of DocumentType properties
-
- public Properties setName (String name) throws InvalidPropertyException
- {
- if (name.length() == 0) throw new InvalidPropertyException("name");
- this.name = name;
- return this;
- }
- public Properties setResult (ProjectSettings.Step step)
- {
- this.result = String.valueOf(step.getNumber());
- return this;
- }
- public Properties setStep (ProjectSettings.Step... step)
- {
- this.step = "-";
- for (int i=0; i<step.length; i++) this.step = this.step + String.valueOf(step[i].getNumber()) + "-";
- return this;
- }
- public Properties setUses (DocumentType... type)
- {
- this.uses = type;
- return this;
- }
-// - Global validity check
-
- public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (name == null) throw new MissedPropertyException("name");
- if (step == null) throw new MissedPropertyException("path");
- }
- }
-// Database fetch constructor
- protected DocumentType () {
-// -------------------------
- }
-// Initialization constructor
- protected DocumentType (Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// -----------------------------------------
- super(dprop); // Throws one of the above exception if not valid
- name = dprop.name;
- state = ProgressState.inCHECK;
- step = dprop.step;
- result = dprop.result; // May be null
- uses = new HashSet<DocumentType>();
- if (dprop.uses != null) for (int i=0; i<dprop.uses.length; i++) uses.add(dprop.uses[i]);
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean approve () {
-// -------------------------
- if (state != ProgressState.inCHECK) return false;
- this.state = ProgressState.APPROVED; // The type name is supposed being localized
- Database.getSession().update(this);
- return true;
- }
-
- public boolean equals(Object entity) {
-// ------------------------------------
- if (entity == null) return false;
- if (entity instanceof String) {
- return this.name.equals((String)entity); // Names are unique
- } else
- if (entity instanceof DocumentType) {
- DocumentType object = (DocumentType)entity;
- int he = object.getIndex();
- int me = this.getIndex();
- if (me*he != 0) return (he == me);
- else return this.getName().equals(object.getName());
- } else {
- return false;
- }
- }
-
- public String getName () {
-// ------------------------
- return name;
- }
-
- public Set<DocumentType> getDefaultUses () {
-// -------------------------------------------
- return uses;
- }
-
- public boolean isApproved () {
-// ----------------------------
- return (state == ProgressState.APPROVED);
- }
-
-/**
- * Checks if documents of this type are attached to the given study step, either as result or content.
- *
- * @param step the involved study step
- * @return true if documents of this type are attached to the given step.
- * @see #isResultOf(org.splat.som.ProjectSettings.Step)
- */
- public boolean isContentInto (ProjectSettings.Step step) {
-// --------------------------------------------------------
- String[] path = this.step.split("-");
- for (int i=0; i<path.length; i++) {
- String value = path[i];
- if (value.length() == 0) continue;
- if (Integer.valueOf(value) == step.getNumber()) return true;
- }
- return false;
- }
-
-/**
- * Checks if documents of this type are result of any study step.
- *
- * @return true if documents of this type are result of a step.
- * @see #isStudyResult()
- * @see #isResultOf(org.splat.som.ProjectSettings.Step)
- */
- public boolean isStepResult () {
-// ------------------------------
- return (result != null);
- }
-
-/**
- * Checks if documents of this type are result of a study.
- * A document is the result of a study when it is the result of the last step of the study.
- *
- * @return true if documents of this type are result of a study.
- * @see #isStepResult()
- * @see #isResultOf(org.splat.som.ProjectSettings.Step)
- */
- public boolean isStudyResult () {
-// -------------------------------
- List<ProjectSettings.Step> step = ProjectSettings.getAllSteps();
- ProjectSettings.Step lastep = step.get( step.size()-1 );
- return (this.isResultOf(lastep));
- }
-
-/**
- * Checks if documents of this type are result of the given study step.
- *
- * @param step the involved study step
- * @return true if documents of this type are result of the given step.
- * @see #isContentInto(org.splat.som.ProjectSettings.Step)
- * @see #isStepResult()
- * @see #isStudyResult()
- */
- public boolean isResultOf (ProjectSettings.Step step) {
-// -----------------------------------------------------
- if (result == null) return false;
- return (Integer.valueOf(result) == step.getNumber());
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class whose only purpose is to represent the kernel's Entity class for propagating to this package the visibility of relations
- * and attributes editing functions.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Set;
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-import org.splat.kernel.ObjectProperties;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-
-
-public abstract class Entity extends org.splat.kernel.Entity {
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected Entity () {
- }
-// Initialization constructor
- protected Entity (ObjectProperties prop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// ----------------------------------------
- super(prop);
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected Relation addRelation (Relation link) {
-// ----------------------------------------------
- return super.addRelation(link);
- }
-
- protected Set<Relation> getAllRelations () {
-// ------------------------------------------
- return super.getAllRelations();
- }
-
- protected void removeRelation (Class<? extends Relation> type, Persistent to) {
-// -----------------------------------------------------------------------------
- super.removeRelation(type, to);
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.File" table="file" lazy="false">
-
-<!-- Properties inherited Persistent
- -->
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
-<!-- File properties
- -->
- <!-- String format -->
- <property name="format" column="format" access="field" not-null="true" />
-
- <!-- String path -->
- <property name="path" column="path" access="field" not-null="true" />
-
- <!-- String date -->
- <property name="date" column="date" access="field" not-null="true" />
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class of meta files representing physical files under the control of Study Manager.
- * Typically, the files represented by this class are source files of Documents and exports in different formats.
- * The path of such files is relative to the vault of the repository of Study Manager.
- * When creating a Document, as the source file is produced by the caller which creates the Document, the corresponding
- * physical file may not exist at instantiation time.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Calendar;
-import java.util.Date;
-
-import org.splat.kernel.Persistent;
-
-
-public class File extends Persistent {
-
-// Persistent fields
- protected String format;
- protected String path;
- protected Date date;
-
-// Transient fields
- private java.io.File myfile; // For optimization
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected File () {
-// -----------------
- this.myfile = null;
- }
-// Internal constructors
- protected File (String path) {
-// ----------------------------
- Calendar current = Calendar.getInstance();
- String[] table = path.split("\\x2E");
-
- this.format = table[table.length-1];
- this.path = path; // The corresponding physical file may not exist yet
- this.date = current.getTime(); // Today
- this.myfile = null;
- }
- protected File (String path, String format, Date date) {
-// ------------------------------------------------------
- this.path = path; // The corresponding physical file may not exist yet
- this.format = format; // The format name may be different from the physical file extension
- this.date = date;
- if (date == null) {
- Calendar current = Calendar.getInstance();
- this.date = current.getTime(); // Today
- }
- this.myfile = null;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-/**
- * Returns the data file associated to this meta file.
- *
- * @return the associated data file. If this meta data is an empty document, the returned file does not exist.
- */
- public java.io.File asFile () {
-// -----------------------------
- if (myfile == null) myfile = new java.io.File(Database.getRepositoryVaultPath() + path);
- return myfile;
- }
-
- public Date getDate () {
-// ----------------------
- return date;
- }
-
- public String getFormat () {
-// --------------------------
- return format;
- }
-
- public String getName () {
-// ------------------------
- return this.asFile().getName();
- }
-
- public String getRelativePath () {
-// --------------------------------
- return path;
- }
-
- public boolean exists () { // Shortcut
-// ------------------------
- return (this.asFile().exists());
- }
-
-// ==============================================================================================================================
-// Protected service
-// ==============================================================================================================================
-
- protected void changePath (String path) {
-// ---------------------------------------
- this.path = path;
- this.myfile = null;
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.IDBuilder" table="refid">
-
- <!-- Integer cycle -->
- <id name="cycle" column="cycle" access="field">
- <generator class="assigned"/>
- </id>
-
- <!-- Integer base -->
- <property name="base" column="base" access="field" />
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.text.DecimalFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-
-public class IDBuilder {
-
- @SuppressWarnings("unused")
- private int cycle;
- private int base; // Number of studies created in this cycle
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
- protected IDBuilder () {
- }
- protected IDBuilder (Date date) {
-// -------------------------------
- SimpleDateFormat get = new SimpleDateFormat("yyyy");
- String year = get.format(date);
- cycle = Integer.valueOf(year);
- base = 0;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- protected String buildReference (String pattern, Study study) {
-// -------------------------------------------------------------
- char[] format = pattern.toCharArray();
- char[] ref = new char[80]; // Better evaluate the length of the generated string
- int next = base + 1;
-
- int count = 0;
- for (int i=0; i<format.length; i++) {
-
-// Insertion of attribute values
- if (format[i] == '%') {
- i += 1;
-
- if (format[i] == 'y') { // Insertion of year in format 2 (e.g. 09) or 4 (e.g. 2009) digits
- int n = i;
- while (format[i] == 'y') {
- i += 1;
- if (i == format.length) break;
- }
- SimpleDateFormat tostring = new SimpleDateFormat("yyyy");
- String year = tostring.format(study.getDate());
- year = year.substring(4-(i-n), 4); // 4-(i-n) must be equal to either 0 or 2
- for (int j=0; j<year.length(); j++) {
- ref[count] = year.charAt(j);
- count += 1;
- }
- i -= 1; // Back to the last 'y' character
- } else
- if (format[i] == '0') { // Insertion of the index
- int n = i;
- while (format[i] == '0') {
- i += 1;
- if (i == format.length) break;
- }
- DecimalFormat tostring = new DecimalFormat(pattern.substring(n, i));
- String number = tostring.format(next);
- for (int j=0; j<number.length(); j++) {
- ref[count] = number.charAt(j);
- count += 1;
- }
- i -= 1; // Back to the last '0' character
- }
-// Keep the character
- } else {
- ref[count] = format[i];
- count += 1;
- }
- }
-// Incrementation of the number of study
- base = next;
- Database.getSession().update(this);
- return String.copyValueOf(ref, 0, count);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-import org.apache.lucene.store.LockObtainFailedException;
-import org.apache.lucene.util.Version;
-import org.splat.kernel.User;
-
-
-class Index {
-
- private Directory index;
- private org.apache.lucene.document.Document body;
-
- protected static StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
- private static final Logger logger = Logger.getLogger(Index.class);
-
- private class Entry extends IndexWriter {
-// ---------------------------------------
- private org.apache.lucene.document.Document entry;
-
- private Entry (Study study) throws CorruptIndexException, LockObtainFailedException, IOException
- {
- super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
-
-// Addition of mandatory fields
- entry = new org.apache.lucene.document.Document();
- Field field;
- field = body.getField("index");
- field.setValue(String.valueOf(study.getIndex()));
- entry.add(field);
- field = body.getField("class");
- field.setValue("Study");
- entry.add(field);
- field = body.getField("type");
- field.setValue(""); // Reserved for configurable Study type
- entry.add(field);
- field = body.getField("ref");
- field.setValue(study.getReference());
- entry.add(field);
- field = body.getField("area");
- field.setValue(study.getVisibility().toString());
- entry.add(field);
- field = body.getField("state");
- field.setValue(study.getProgressState().toString());
- entry.add(field);
- field = body.getField("author");
- field.setValue(study.getAuthor().toString());
- entry.add(field);
- field = body.getField("title");
- field.setValue(study.getTitle());
- entry.add(field);
- field = body.getField("contents");
- field.setValue(study.getTitle());
- entry.add(field);
-
-// Addition of optional fields
- setActorsOf(study);
- setContextAt(study.getSteps());
- }
- private Entry (KnowledgeElement kelm) throws CorruptIndexException, LockObtainFailedException, IOException
- {
- super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
-
-// Addition of mandatory fields
- entry = new org.apache.lucene.document.Document();
- Field field;
- field = body.getField("index");
- field.setValue(String.valueOf(kelm.getIndex()));
- entry.add(field);
- field = body.getField("class");
- field.setValue("KnowledgeElement");
- entry.add(field);
- field = body.getField("type");
- field.setValue(kelm.getType().getName());
- entry.add(field);
- field = body.getField("ref");
- field.setValue(kelm.getReference());
- entry.add(field);
- field = body.getField("area");
- field.setValue(kelm.getVisibility().toString());
- entry.add(field);
- field = body.getField("state");
- field.setValue(kelm.getProgressState().toString());
- entry.add(field);
- field = body.getField("author");
- field.setValue(kelm.getAuthor().toString());
- entry.add(field);
- field = body.getField("title");
- field.setValue(kelm.getTitle());
- entry.add(field);
- field = body.getField("contents");
- field.setValue(kelm.getTitle());
- entry.add(field);
-
-//TODO: Addition of optional fields
- Scenario scene = kelm.getOwnerScenario();
- Study study = scene.getOwnerStudy();
- setActorsOf(study); // For restricting the visibility of knowledges attached to private studies
- setContextAt(study.getSteps());
- setContextAt(scene.getSteps());
- }
- private void add () throws CorruptIndexException, IOException
- {
- addDocument(entry);
-// Save the new entry
- optimize(); // Should be called before committing the index
- close(); // Commits the index
- }
- private void update () throws CorruptIndexException, IOException
- {
- String value = entry.getField("ref").stringValue(); // Only field with unique value
- Term term = new Term("ref").createTerm(value);
- updateDocument(term, entry);
-// Save the updated entry
- optimize(); // Should be called before committing the index
- close(); // Commits the index
- }
- private void setContextAt (Step[] step)
- {
- for (int i=0; i<step.length; i++) {
- List<SimulationContext> contexts = step[i].getAllSimulationContexts();
- for (Iterator<SimulationContext> j=contexts.iterator(); j.hasNext();) {
- SimulationContext context = j.next();
- String type = String.valueOf(context.getType().getIndex());
- String value = context.getValue();
- entry.add( new Field(type, value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
- }
- }
- }
- private void setActorsOf (Study study)
- {
- Set<User> actors = study.getActors();
- for (Iterator<User> i=actors.iterator(); i.hasNext(); ) {
- String value = i.next().toString();
- entry.add( new Field("actor", value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
- }
- }
- }
- public static class ObjectProxy implements Proxy, Serializable {
-// --------------------------------------------------------------
- private int rid;
- private String sid;
- private ProgressState state;
- private String title;
- private String type;
- private String name;
- private static final long serialVersionUID = -4386494192709562221L;
-
- public ObjectProxy (org.apache.lucene.document.Document ludoc) {
- rid = Integer.valueOf(ludoc.get("index"));
- sid = ludoc.get("ref");
- state = ProgressState.valueOf(ludoc.get("state"));
- title = ludoc.get("title");
- name = ludoc.get("author");
- }
- public String getAuthorName () {
- return name;
- }
- public Integer getIndex () {
- return rid;
- }
- public ProgressState getProgressState () {
- return state;
- }
- public String getReference () {
- return sid;
- }
- public String getTitle () {
- return title;
- }
- public String getType () {
- return type;
- }
- }
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
- protected static void create () throws IOException {
-// -------------------------------
- Directory index = FSDirectory.open(Database.getRepositoryIndexDirectory());
- IndexWriter writer = new IndexWriter(index, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
- writer.close(); // ==== Creates an empty index
- }
-
- protected Index () throws IOException {
-// ------------------
- File indir = Database.getRepositoryIndexDirectory();
- index = FSDirectory.open(indir);
- body = new org.apache.lucene.document.Document();
- body.add( new Field("index", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
- body.add( new Field("class", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
- body.add( new Field("type", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
- body.add( new Field("ref", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
- body.add( new Field("area", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
- body.add( new Field("state", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
- body.add( new Field("author", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
- body.add( new Field("title", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
- body.add( new Field("contents","", Field.Store.NO, Field.Index.ANALYZED) );
- }
-
-// ==============================================================================================================================
-// Member functions
-// ==============================================================================================================================
-
- protected void add (Study study) throws IOException {
-// --------------------------------
- Index.Entry entry = new Entry(study);
- entry.add();
- if (logger.isInfoEnabled()) {
- logger.info("Study \"" + study.getIndex() + "\" indexed.");
- }
- }
-
- protected void add (KnowledgeElement kelm) throws IOException {
-// ------------------------------------------
- Index.Entry entry = new Entry(kelm);
- entry.add();
- if (logger.isInfoEnabled()) {
- logger.info("Knowledge \"" + kelm.getIndex() + "\" indexed.");
- }
- }
-
- protected boolean exists () {
-// ---------------------------
- try {
- return IndexReader.indexExists(index);
- }
- catch (IOException error) {
- error.printStackTrace();
- return false;
- }
- }
-
- protected void update (Study study) throws IOException {
-// -----------------------------------
- Index.Entry entry = new Entry(study);
- entry.update();
- if (logger.isInfoEnabled()) {
- logger.info("Study \"" + study.getIndex() + "\" re-indexed.");
- }
- }
-
- protected void update (KnowledgeElement kelm) throws IOException {
-// ---------------------------------------------
- Index.Entry entry = new Entry(kelm);
- entry.update();
- if (logger.isInfoEnabled()) {
- logger.info("Knowledge \"" + kelm.getIndex() + "\" re-indexed.");
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.KnowledgeElement" table="knowelm" lazy="false">
-
-<!-- Properties inherited Persistent
- -->
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
-<!-- KnowledgeElement properties
- -->
- <!-- KnowledgeElementType type -->
- <many-to-one name="type" column="type" access="field" not-null="true" />
-
- <!-- String title -->
- <property name="title" column="title" access="field" not-null="true" />
-
- <!-- String value -->
- <property name="value" column="value" access="field" not-null="true" />
-
- <!-- Scenario owner -->
- <many-to-one name="owner" column="owner" access="field" not-null="true" />
-
- <!-- ProgressState state -->
- <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
-
- <!-- User author -->
- <many-to-one name="author" column="author" access="field" not-null="true" />
-
- <!-- Date date -->
- <property name="date" column="date" access="field" not-null="true" />
-
- </class>
-
-<!-- Class KnowledgeElementType
- -->
- <class name="org.splat.som.KnowledgeElementType" table="knowtype" lazy="false">
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
- <property name="name" column="name" access="field" not-null="true" />
- <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.text.DecimalFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Vector;
-
-import org.hibernate.Session;
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.User;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-
-
-public class KnowledgeElement extends Persistent {
-
- private KnowledgeElementType type; // User extendable types
- private Scenario owner;
- private ProgressState state;
- private String title;
- private String value;
- private User author;
- private Date date;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private String kid = null; // Search criterion only
- private KnowledgeElementType type = null;
- private Scenario owner = null;
- private Visibility visibility = null; // Search criterion only
- private ProgressState state = null;
- private String title = null;
- private String value = null;
- private User author = null;
- private User actor = null; // Search criterion only
- private Date date = null;
- private List<SimulationContext> context = new Vector<SimulationContext>(); // Search criterion only
-
-// - Public services
-
- public void clear () {
- super.clear();
- kid = null;
- type = null;
- owner = null;
- visibility = null;
- state = null;
- title = null;
- value = null;
- author = null;
- actor = null;
- date = null;
- context = new Vector<SimulationContext>(); // as clear() may generate side effects
- }
- public Properties copy () {
- Properties copy = new Properties();
- copy.kid = this.kid;
- copy.type = this.type;
- copy.owner = this.owner;
- copy.visibility = this.visibility;
- copy.state = this.state;
- copy.title = this.title;
- copy.value = this.value;
- copy.author = this.author;
- copy.actor = this.actor;
- copy.date = this.date;
- copy.context = this.context;
- return copy;
- }
-// - Protected services
-
- protected User getActor () {
- return actor;
- }
- protected User getAuthor () {
- return author;
- }
- protected ProgressState getProgressState () {
- return state;
- }
- protected String getReference () {
- return kid;
- }
- protected List<SimulationContext> getSimulationContexts () {
- return context;
- }
- protected String getTitle () {
- return title;
- }
- protected KnowledgeElementType getType () {
- return type;
- }
- protected Visibility getVisibility () {
- return visibility;
- }
-// - Property setters
-
-// For building a search query
- public Properties setActor (User actor)
- {
- this.actor = actor;
- return this;
- }
- public Properties setAuthor (User user)
- {
- this.author = user;
- return this;
- }
- public Properties setDate (Date date)
- {
- this.date = date;
- return this;
- }
- protected Properties setOwnerScenario (Scenario owner)
- {
- this.owner = owner;
- return this;
- }
-// For building a search query
- public Properties setReference (String kid) throws InvalidPropertyException
- {
- if (kid.length() == 0) throw new InvalidPropertyException("reference");
- this.kid = kid;
- return this;
- }
-// For building a search query
- public Properties setSimulationContexts (List<SimulationContext> context) {
- this.context = context;
- return this;
- }
- public Properties setState (ProgressState state) throws InvalidPropertyException
- {
- if (state != ProgressState.inWORK && state != ProgressState.inDRAFT && state != ProgressState.inCHECK && state != ProgressState.APPROVED) {
- throw new InvalidPropertyException("state");
- }
- this.state = state;
- return this;
- }
- public Properties setTitle (String title) throws InvalidPropertyException
- {
- if (title.length() == 0) throw new InvalidPropertyException("title");
- this.title = title;
- return this;
- }
- public Properties setType (KnowledgeElementType type)
- {
- this.type = type;
- return this;
- }
- public Properties setValue (String value) throws InvalidPropertyException
- {
- if (value.length() == 0) throw new InvalidPropertyException("value");
- this.value = value;
- return this;
- }
-// For building a search query
- public Properties setVisibility (Visibility area)
- {
- this.visibility = area;
- return this;
- }
-// - Global validity check
-
- public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (type == null) throw new MissedPropertyException("type");
- if (owner == null) throw new MissedPropertyException("owner");
- if (title == null) throw new MissedPropertyException("title");
- if (value == null) throw new MissedPropertyException("value");
- if (author == null) throw new MissedPropertyException("author");
- }
- }
-// Database fetch constructor
- protected KnowledgeElement () {
- }
-// Internal constructor
- protected KnowledgeElement (Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
- super(kprop); // Throws one of the above exception if not valid
- type = kprop.type;
- owner = kprop.owner;
- title = kprop.title;
- author = kprop.author;
-
- date = kprop.date;
- if (date == null) {
- Calendar current = Calendar.getInstance();
- date = current.getTime(); // Today
- }
- state = kprop.state;
- if (state == null) {
- if (type.isReserved()) state = ProgressState.inWORK;
- else state = ProgressState.inDRAFT;
- }
- value = kprop.value.trim();
- if (!value.startsWith("<p>")) {
- StringBuffer text = new StringBuffer("<p>");
- int index = value.indexOf("<p>");
- if (index > 0) {
- value = text.append(value.substring(0, index)).append("</p>").append(value.substring(index)).toString();
- } else {
- value = text.append(value).append("</p>").toString();
- }
- }
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean approve () {
-// -------------------------
- if (state != ProgressState.inCHECK) return false;
- state = ProgressState.APPROVED;
- return updateMe();
- }
-
- public boolean demote () {
-// ------------------------
- if (state != ProgressState.APPROVED && state != ProgressState.inCHECK) return false;
- state = ProgressState.inDRAFT;
- return updateMe();
- }
-
- public boolean equals (KnowledgeElement given) {
-// ----------------------------------------------
- if (isSaved()) return (this.getIndex() == given.getIndex());
- if (!this.getType().getName().equals(given.getType().getName())) return false;
- if (this.getValue().equals(given.getValue())) return true;
- return false;
- }
-
- public User getAuthor () {
-// ------------------------
- return author;
- }
-
- public Date getDate () {
-// ----------------------
- return date;
- }
-
- public Scenario getOwnerScenario () {
-// -----------------------------------
- return owner;
- }
-
- public ProgressState getProgressState () {
-// ----------------------------------------
- return state;
- }
-
- public String getTitle () {
-// -------------------------
- return title;
- }
-
- public String getReference () {
-// -----------------------------
- DecimalFormat toString = new DecimalFormat("00000"); // Supports 99 999 knowledge elements
- return "KE" + toString.format(this.getIndex());
- }
-
- public KnowledgeElementType getType () {
-// --------------------------------------
- return type;
- }
-
- public String getValue () {
-// -------------------------
- return value;
- }
-
- public Visibility getVisibility () {
-// ----------------------------------
- return getOwnerScenario().getOwnerStudy().getVisibility();
- }
-
- public boolean promote () {
-// -------------------------
- if (state != ProgressState.inDRAFT) return false;
- state = ProgressState.inCHECK;
- return updateMe();
- }
-
- public void rename (String title) throws InvalidPropertyException {
-// ---------------------------------
- if (title.length() == 0) throw new InvalidPropertyException("name");
- this.title = title;
- updateMe();
- }
-
- public void update (String description) {
-// ---------------------------------------
- value = description.trim();
- if (!value.startsWith("<p>")) {
- StringBuffer text = new StringBuffer("<p>");
- int index = value.indexOf("<p>");
- if (index > 0) {
- value = text.append(value.substring(0, index)).append("</p>").append(value.substring(index)).toString();
- } else {
- value = text.append(value).append("</p>").toString();
- }
- }
- Database.getSession().update(this); // No need to update the Lucene index
- }
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public static KnowledgeElementType createType (String name) throws RuntimeException {
-// -----------------------------------------------------------
-//TODO: Check for duplicate definition
- KnowledgeElementType kelt = new KnowledgeElementType(name);
- Session session = Database.getSession();
- session.save(kelt);
-
- return kelt;
- }
-
- @SuppressWarnings("unchecked")
- public static List<KnowledgeElementType> selectAllTypes () {
-// ----------------------------------------------------------
- StringBuffer query = new StringBuffer("from KnowledgeElementType");
- query = query.append(" order by rid asc");
- return Database.getSession().createQuery(query.toString()).list();
- }
-
- @SuppressWarnings("unchecked")
- public static List<KnowledgeElementType> selectTypesWhere (ProgressState state) {
-// -------------------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from KnowledgeElementType where state='").append(state).append("'");
- query = query.append(" order by rid asc");
- return Database.getSession().createQuery(query.toString()).list();
- }
-
- public static KnowledgeElementType selectType (String name) {
-// -----------------------------------------------------------
- StringBuffer query = new StringBuffer("from KnowledgeElementType where name='").append(name).append("'");
- return (KnowledgeElementType)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static KnowledgeElementType selectType (int index) {
-// ---------------------------------------------------------
- StringBuffer query = new StringBuffer("from KnowledgeElementType where rid='").append(index).append("'");
- return (KnowledgeElementType)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected boolean updateMe () {
-// -----------------------------
- try {
- Database.getSession().update(this);
- Database.getIndex().update(this);
- return true;
- }
- catch (Exception error) {
-// logger.error("Unable to re-index the knowledge '" + getIndex() + "', reason:", error);
- return false;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-
-
-public class KnowledgeElementType extends Persistent {
-
- private String name;
- private ProgressState state;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected KnowledgeElementType () {
- }
-// Initialization constructor
- protected KnowledgeElementType (String name) {
-// --------------------------------------------
- super();
- this.name = name;
- this.state = ProgressState.inCHECK;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean approve () {
-// -------------------------
- if (state != ProgressState.inCHECK) return false;
- this.state = ProgressState.APPROVED; // The type name is supposed being localized
- if (this.isSaved()) Database.getSession().update(this);
- return true;
- }
-
- public boolean equals(Object entity) {
-// ------------------------------------
- if (entity == null) return false;
- if (entity instanceof String) {
- return this.name.equals((String)entity); // Names are unique
- } else
- if (entity instanceof KnowledgeElementType) {
- KnowledgeElementType object = (KnowledgeElementType)entity;
- int he = object.getIndex();
- int me = this.getIndex();
- if (me*he != 0) return (he == me);
- else return this.getName().equals(object.getName());
- } else {
- return false;
- }
- }
-
- public String getName () {
-// ------------------------
- return name;
- }
-
- public boolean isApproved () {
-// ----------------------------
- return (state == ProgressState.APPROVED);
- }
-
- public boolean isReserved () {
-// ----------------------------
- return (state == ProgressState.inWORK);
- }
-
-// ==============================================================================================================================
-// Protected service
-// ==============================================================================================================================
-/**
- * Reserves this type for the management of simulation contexts.
- * For being able to get the studies in which simulation contexts are used, all study scenarios are indexed through this
- * knowledge element type, whether they include knowledge elements or not.
- */
- protected boolean reserve () {
-// ----------------------------
- if (state != ProgressState.inCHECK) return false;
- this.state = ProgressState.inWORK;
- if (this.isSaved()) Database.getSession().update(this);
- return true;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public enum Profile {
- studengineer, // Standard user working on simulation studies
- manager, // User with study creation right
- knowledgineer, // Knowledge Engineer in charge of the management of simulation contexts and knowledge elements
- sysadmin, // System Administrator in charge of administration of the database
- customer
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public enum ProgressState {
- inPROGRESS, // Represents inWORK, inDRAFT and inCHECK states for search purpose
- inWORK, inDRAFT, inCHECK, APPROVED,
- EXTERN, // Document-specific state representing documents produced outside studies
- TEMPLATE // Study-specific state qualifying typical reference studies
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of properties common to Study and Scenario
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.ProjectElement" abstract="true">
-
-<!-- Properties inherited from Entity
- -->
- <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
- <generator class="org.splat.kernel.IDGenerator"/>
- </id>
- <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Attribute" />
- </set>
- <set name="relations" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Relation" />
- </set>
-
-<!-- ProjectElement properties common to Study and Scenario
- -->
- <property name="title" column="title" access="field" not-null="true" />
- <property name="credate" column="credate" access="field" not-null="true" />
- <property name="lasdate" column="lasdate" access="field" not-null="true" />
- <many-to-one name="manager" column="manager" access="field" not-null="true" />
- <list name="contex" table="projext" lazy="false" access="field">
- <key column="owner" />
- <list-index column="ordex" />
- <many-to-many column="rid" class="org.splat.som.SimulationContext" />
- </list>
- <set name="docums" inverse="true" lazy="false" order-by="`rid` desc" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.som.Publication" />
- </set>
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-
-import org.apache.log4j.Logger;
-
-import org.splat.kernel.ObjectProperties;
-import org.splat.kernel.User;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-
-
-public abstract class ProjectElement extends Entity {
-
-// Persistent fields
- protected String title;
- protected User manager;
- protected Date credate; // Object creation date
- protected Date lasdate; // Object Last modification date
- private List<SimulationContext> contex; // Structured by the Step transient class
- private Set<Publication> docums; // Structured by the Step transient class
-
-// Transient field
- private Step[] folders;
-
- protected final static Logger logger = Logger.getLogger(ProjectElement.class);
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected ProjectElement () {
-// ---------------------------
- folders = null;
- }
-// Initialization constructor
- protected ProjectElement (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// -------------------------------------------------
- super(oprop); // Throws one of the above exception if not valid
- title = null; // Initialized by subclasses
- credate = null; // Initialized by subclasses
- lasdate = null; // Initialized by subclasses
- docums = new LinkedHashSet<Publication>();
- contex = new Vector<SimulationContext>();
-
- folders = null;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public User getAuthor () {
-// ------------------------
- return manager;
- }
-
-/**
- * Returns the creation date of this Project Element.
- */
- public Date getDate () {
-// ----------------------
- return credate;
- }
-
- public String getDescription () {
-// -------------------------------
- String summary = null;
- DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
- if (field != null) summary = field.getValue();
- return summary; // May be null
- }
-
- public Step getFirstStep () {
-// ---------------------------
- return this.getSteps()[0];
- }
-
- public Date getLastModificationDate () {
-// --------------------------------------
- return lasdate;
- }
-
- public Step getLastStep () {
-// --------------------------
- Step[] mystep = this.getSteps(); // For getting the folders length, if null
- return mystep[mystep.length-1];
- }
-
-/**
- * Returns the publication into this Project Element of the given document version, if exists.
- * If exists, a document publication id unique in a given ProjectElement.
- *
- * @param doc a document version published into this Project Element
- * @return the publication of the document version, or null if the given document version is not published into this Project Element
- */
- public Publication getPublication (Document doc) {
-// ------------------------------------------------
- int index = doc.getIndex();
- for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
- Publication found = i.next();
- if (found.value().getIndex() == index) return found; // A document publication is unique in a given ProjectElement
- }
- return null;
- }
-
- public Step[] getSteps () {
-// -------------------------
- if (folders == null) {
- List<ProjectSettings.Step> steps = ProjectSettings.getStepsOf(this.getClass());
- Iterator<ProjectSettings.Step> nstep = steps.iterator();
-
- folders = new Step[steps.size()];
- for (int i=0; i<folders.length; i++) {
- folders[i] = new Step(nstep.next(), this);
- }
- }
- return folders; // No protection against this object corruption as it would not corrupt the database
- }
-
- public String getTitle () {
-// -------------------------
- return title;
- }
-
- public boolean publishes (Document doc) {
-// ---------------------------------------
- int index = doc.getIndex();
- for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
- Document found = i.next().value();
- if (found.getIndex() == index) return true;
- }
- return false;
- }
-
- public Iterator<Publication> PublicationIterator () {
-// ---------------------------------------------------
- return Collections.unmodifiableSet(docums).iterator();
- }
-
- public Iterator<SimulationContext> SimulationContextIterator () {
-// ---------------------------------------------------------------
- return Collections.unmodifiableList(contex).iterator();
- }
-
-// ==============================================================================================================================
-// Protected member functions
-// ==============================================================================================================================
-
- protected boolean add (Publication newdoc) {
-// ------------------------------------------
- return docums.add(newdoc);
- }
-
- protected boolean add (SimulationContext newdoc) {
-// ------------------------------------------------
- return contex.add(newdoc);
- }
-
- protected boolean remove (Publication oldoc) {
-// --------------------------------------------
- return docums.remove(oldoc); // The removed tag becoming orphan, it is supposed automatically deleted from the data store
- }
-
- protected boolean remove (SimulationContext oldoc) {
-// --------------------------------------------------
- return contex.remove(oldoc);
- }
-
-/**
- * Refreshes the internal data potentially out-of-date.
- * This function needs to be called when Publication objects are added to this Project Element before being saved. The reason is,
- * as saving a persistent object changes its hashcode, hashed data need to be rebuilt after saving for making functions based
- * on this hashcode such as remove(), working.
- */
- protected void refresh () {
-// -------------------------
- Publication[] curdoc = docums.toArray(new Publication[docums.size()]);
-
- folders = null; // Just in case
- docums.clear();
- for (int i=0; i<curdoc.length; i++) docums.add(curdoc[i]);
-// No need to rebuild the list of SimulationContext as it does not use hashcodes
- Database.getSession().update(this);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Vector;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import org.splat.kernel.XDOM;
-import org.splat.som.ValidationCycle.Actor;
-
-
-public class ProjectSettings {
-
-// Non persistent configuration information
- private Properties reprop; // Repository settings
- private String pattern; // Pattern of study references
- private FileNaming naming; // Scheme of file names stored into the repository
- private String versioning; // Pattern of the presentation of version numbers
- private Vector<Step> steps; // Ordered list of (transient) study steps
- private Vector<ValidationCycle> concycles; // Configuration document validation cycles
-
-// Temporary attributes initialized from the configuration file for populating the database with object types
- private LinkedHashMap<String,String> mapuse; // Document type names and uses mapping
- private Vector<String> context; // Simulation Context type names
- private Vector<String> kname; // Knowledge Element type names
- private Vector<NamedNodeMap> flows; // Document flows
- private Vector<NamedNodeMap> sclass; // Study classifications
-
-// Other resources
- private static ProjectSettings my = null; // Singleton instance
- protected final static Logger logger = Logger.getLogger(ProjectSettings.class);
-
- protected enum FileNaming { title, encoded, asis }
- public static class Step {
-// ------------------------
- private int number;
- private Class<? extends ProjectElement> level; // Study or Scenario
- private Set<Class<?>> contents; // Set of Document and/or Knowledge
- private String path;
-
- private Step (int number, Class<? extends ProjectElement> level, String path) {
- this.initialize(number, level, path);
- }
- private Step (int number, Class<? extends ProjectElement> level, Class<?> contents, String path) {
- this.initialize(number, level, path);
- this.contents.add(contents);
- }
- private void initialize (int number, Class<? extends ProjectElement> level, String path) {
- this.number = number;
- this.level = level;
- this.path = path + "/";
- this.contents = new HashSet<Class<?>>();
- }
- public boolean appliesTo (Class<? extends ProjectElement> level) {
- return (level == this.level);
- }
- public boolean mayContain (Class<?> type) {
- return contents.contains(type);
- }
- public int getNumber () {
- return number;
- }
- public String getPath () {
- return path;
- }
- }
- public static class ValidationCycle {
-// -----------------------------------
- private String name;
- private Actor[] actor;
-
- private ValidationCycle () {
- this.name = "built-in";
- this.actor = new Actor[] { null, null, null };
- }
- private ValidationCycle (String name, Actor[] actor) {
- this.name = name;
- this.actor = actor;
- }
- public String getName () {
- return name;
- }
- public Actor[] getActorTypes () {
- return actor;
- }
- }
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
- public static ProjectSettings getMe () {
-// --------------------------------------
- if (my == null) my = new ProjectSettings();
- return my;
- }
- protected ProjectSettings () {
-// ----------------------------
- reprop = new Properties();
- steps = new Vector<Step>();
- }
-
-// ==============================================================================================================================
-// Public functions
-// ==============================================================================================================================
-
- public void configure (String filename) throws IOException, SQLException {
-// ---------------------------------------
- if (!steps.isEmpty()) return; // Project already configured
-
- Database base = Database.getMe();
- File config = new File(filename);
- if (config.exists()) {
- loadCustomization(config);
- } else {
- logger.fatal("Could not find the database configuration file \"" + config.getAbsolutePath() + "\"");
- throw new FileNotFoundException();
- }
- base.configure(reprop);
- if (!base.isInitialized()) {
- base.initialize();
-//TODO: Move the second part of loadCustomization here
- }
- }
-
- public static List<Step> getAllSteps () {
-// ---------------------------------------
- return my.steps;
- }
-
-/**
- * Return the validation cycles of result documents defined in the workflow, ordered by study activities
- * and ending by the default validation cycle, if defined.
- *
- * @return the validation cycles of the workflow
- */
- public static List<ValidationCycle> getAllValidationCycles () {
-// -------------------------------------------------------------
- return my.concycles;
- }
-
- public static FileNaming getFileNamingScheme () {
-// -----------------------------------------------
- return my.naming;
- }
-
- public static ValidationCycle getNewValidationCycle () {
-// ------------------------------------------------------
- return new ValidationCycle();
- }
-
- public static String getReferencePattern () {
-// -------------------------------------------
- return my.pattern;
- }
-
- public static String getRevisionPattern () {
-// ------------------------------------------
- return my.versioning;
- }
-
- public static Step getStep (int number) {
-// ---------------------------------------
- for (int i=0; i<my.steps.size(); i++) {
- Step step = my.steps.get(i);
- if (step.number == number) return step;
- }
- return null;
- }
-
- public static List<Step> getStepsOf (Class<? extends ProjectElement> level) {
-// ---------------------------------------------------------------------------
- Vector<Step> result = new Vector<Step>();
-
- for (int i=0; i<my.steps.size(); i++) {
- Step step = my.steps.get(i);
- if (step.appliesTo(level)) result.add(step);
- }
- return result;
- }
-
-// ==============================================================================================================================
-// Protected member function
-// ==============================================================================================================================
-
- protected void initialize () {
-// ----------------------------
- createDocumentTypes();
- createSimulationContextTypes();
- createKnowledgeElementTypes();
- }
-
-// ==============================================================================================================================
-// Private member function
-// ==============================================================================================================================
-
- private void loadCustomization (File config) {
-// --------------------------------------------
- try {
- DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
- DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
-
- org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
- HashMap<String, Node> children = XDOM.getNamedChildNodes(conf.getDocumentElement());
-
-// Repository tag initializing the reprop attribute
- Node child = children.get("database");
- HashMap<String, Node> datag = XDOM.getNamedChildNodes(child);
-
- String disk = datag.get("repository").getAttributes().getNamedItem("disk").getNodeValue();
- if (!disk.endsWith("/")) disk = disk + "/";
- logger.info("Database root set to " + disk);
- reprop.setProperty("repository", disk);
-
-// Formats tag initializing the reference pattern and date attributes
- child = children.get("formats");
- datag = XDOM.getNamedChildNodes(child);
-
- NamedNodeMap natr = datag.get("references").getAttributes();
- pattern = natr.getNamedItem("study").getNodeValue();
-
- natr = datag.get("files").getAttributes();
- naming = FileNaming.valueOf(natr.getNamedItem("name").getNodeValue());
-
- natr = datag.get("versions").getAttributes();
- versioning = natr.getNamedItem("pattern").getNodeValue();
-
-// Activities tag initializing the steps and rex attributes
- child = children.get("activities");
- NodeList nlist = child.getChildNodes();
- Vector<NamedNodeMap> flist = new Vector<NamedNodeMap>();
- Vector<String> resultype = new Vector<String>();
- Vector<NamedNodeMap> clist = new Vector<NamedNodeMap>();
-
- int snum = 1; // Base number of steps
- for (int i=0; i<nlist.getLength(); i++) {
- child = nlist.item(i);
- if (child.getNodeName().equals("scenario")) {
- NodeList slist = child.getChildNodes();
- for (int j=0; j<slist.getLength(); j++) {
- child = slist.item(j);
- if (!child.getNodeName().equals("step")) continue;
- HashMap<String, Node> tags = XDOM.getNamedChildNodes(child);
-
- natr = tags.get("storage").getAttributes();
- Step step = new Step(snum, Scenario.class, natr.getNamedItem("path").getNodeValue());
-
-// Keeping flow and classification information for eventual later use
- natr = tags.get("flow").getAttributes();
- flist.add(natr);
- child = natr.getNamedItem("result");
- if (child != null) resultype.add(child.getNodeValue());
-
- child = tags.get("classification");
- if (child != null) clist.add( child.getAttributes() );
- else clist.add( null );
-
- if (natr.getNamedItem("contents").getNodeValue().equals("knowledge")) {
-//TODO In a given scenario, only one step must contain knowledges
- step.contents.add(KnowledgeElement.class);
- } else {
- step.contents.add(Document.class);
- }
- steps.add(step);
- snum += 1;
- }
- } else {
- if (!child.getNodeName().equals("step")) continue;
- HashMap<String, Node> tags = XDOM.getNamedChildNodes(child);
-
- natr = tags.get("storage").getAttributes(); // Mandatory information
- Step step = new Step(snum, Study.class, natr.getNamedItem("path").getNodeValue());
-
-// Keeping flow and classification information for eventual later use
- natr = tags.get("flow").getAttributes();
- flist.add(natr);
- child = natr.getNamedItem("result");
- if (child != null) resultype.add(child.getNodeValue());
-
- child = tags.get("classification"); // Optional information
- if (child != null) clist.add( child.getAttributes() );
- else clist.add( null );
-
- if (natr.getNamedItem("contents").getNodeValue().equals("knowledge")) {
-//TODO Error: knowledges must be attached to scenarios
- } else {
- step.contents.add(Document.class);
- }
- steps.add(step);
- snum += 1;
- }
- }
-// Validations tag
- child = children.get("validations");
- concycles = new Vector<ValidationCycle>();
- datag = XDOM.getNamedChildNodes(child);
-
- String[] step = { "review", "approval", "acceptance" };
- resultype.add("default");
- for (Iterator<String> i=resultype.iterator(); i.hasNext(); ) {
- Actor[] actor = { null, null, null };
- String name = i.next();
- child = datag.get(name);
- if (child == null) continue; // Document type not subject of any validation
- natr = child.getAttributes();
- for (int j=0; j<step.length; j++) {
- child = natr.getNamedItem(step[j]);
- if (child == null) continue; // Validation step not required
- actor[j] = Actor.valueOf(child.getNodeValue());
- }
- concycles.add( new ValidationCycle(name, actor) );
- }
- concycles.add( new ValidationCycle() ); // Adds the built-in validation cycle
-
- if (Database.getMe().isInitialized()) return; // No need to load object type definitions as they are already stored
-
-// Documents tag
- child = children.get("documents");
- nlist = child.getChildNodes();
-
- flows = flist; // Kept for later use in document type definition
- sclass = clist; // Kept for later use in simulation context type definition
- mapuse = new LinkedHashMap<String,String>();
- for (int i=0; i<nlist.getLength(); i++) {
- child = nlist.item(i);
- if (!child.getNodeName().equals("article")) continue;
-
- natr = child.getAttributes();
- String type = natr.getNamedItem("type").getNodeValue();
- String uses = null;
- child = natr.getNamedItem("uses");
- if (child != null) uses = child.getNodeValue();
- mapuse.put(type, uses); // Must be added to the map even if no (null) uses
- }
-// Simulation Contexts tag
- child = children.get("contexts");
- nlist = child.getChildNodes();
-
- context = new Vector<String>();
- for (int i=0; i<nlist.getLength(); i++) {
- child = nlist.item(i);
- if (!child.getNodeName().equals("article")) continue;
-
- context.add(child.getAttributes().getNamedItem("type").getNodeValue());
- }
-// Knowledge Elements tag
- child = children.get("knowledges");
- nlist = child.getChildNodes();
-
- kname = new Vector<String>();
- for (int i=0; i<nlist.getLength(); i++) {
- child = nlist.item(i);
- if (!child.getNodeName().equals("article")) continue;
-
- kname.add(child.getAttributes().getNamedItem("type").getNodeValue());
- }
- }
- catch (Exception error) {
- logger.info("Error in customization", error);
- }
- }
-
- private void createDocumentTypes () {
-// -----------------------------------
- DocumentType.Properties tprop = new DocumentType.Properties();
- HashMap<String,Vector<Step>> mapsteps = new HashMap<String,Vector<Step>>();
- HashMap<String,Step> mapresult = new HashMap<String,Step>();
- HashMap<String,DocumentType> maptype = new HashMap<String,DocumentType>();
-
- Vector<Step> slist = null; // List of Steps to which each document type is valid
- int snum = 0; // Step number
- String type = null;
- String uses = null;
- for (Iterator<NamedNodeMap> i=flows.iterator(); i.hasNext(); snum++) {
- NamedNodeMap flow = i.next();
- Step step = steps.get(snum);
- String[] contents = flow.getNamedItem("contents").getNodeValue().split(",");
- for (int j=0; j<contents.length; j++) {
- type = contents[j];
- if (!mapuse.containsKey(type)) {
- logger.warn("Undefined \"" + type + "\" document type.");
- continue;
- } slist = mapsteps.get(type);
- if (slist == null) slist = new Vector<Step>();
- slist.add(step);
- mapsteps.put(type, slist);
- }
- Node result = flow.getNamedItem("result");
- if (result != null) mapresult.put(result.getNodeValue(), step);
- }
- try {
- DocumentType tdoc = null;
- Set<String> tset = mapuse.keySet();
- Step step;
- for (Iterator<String> i=tset.iterator(); i.hasNext(); ) {
- type = i.next();
- slist = mapsteps.get(type);
- uses = mapuse.get(type);
- step = mapresult.get(type);
-
- tprop.clear();
- tprop.setName(type).setStep(slist.toArray(new Step[slist.size()]));
- if (uses != null) {
- tdoc = maptype.get(uses);
- if (tdoc == null) logger.warn("Undefined \"" + uses + "\" document type.");
- else tprop.setUses(tdoc);
- }
- if (step != null) tprop.setResult(step);
-
- tprop.disableCheck();
- tdoc = Document.createType(tprop); // Creation of Document Types
- tdoc.approve();
- maptype.put(type, tdoc);
- }
- } catch (Exception error) {
- logger.warn("Error creating document types, reason:", error); // Should not happen
- }
- }
-
- private void createKnowledgeElementTypes () {
-// -------------------------------------------
- try {
- KnowledgeElementType ktype = KnowledgeElement.createType("usecase"); // Internal reserved knowledge element type
- ktype.reserve();
- for (Iterator<String> i=kname.iterator(); i.hasNext(); ) {
- String type = i.next();
-
- ktype = KnowledgeElement.createType(type); // Knowledge Elements Types defined in the configuration
- ktype.approve();
- }
- } catch (Exception error) {
- logger.warn("Error creating knowledge types, reason:", error); // Should not happen
- }
- }
-
- private void createSimulationContextTypes () {
-// --------------------------------------------
- HashMap<String,Step> mapstep = new HashMap<String,Step>();
- int snum = 0;
- for (Iterator<NamedNodeMap> i=sclass.iterator(); i.hasNext(); snum++) {
- NamedNodeMap clatr = i.next();
- if (clatr == null) continue;
-
- String[] clist = clatr.getNamedItem("context").getNodeValue().split(",");
- for (int j=0; j<clist.length; j++) {
- mapstep.put(clist[j], steps.get(snum));
- }
- }
- try {
- SimulationContextType tctex = null;
- for (Iterator<String> i=context.iterator(); i.hasNext(); ) {
- String type = i.next();
- if (!mapstep.containsKey(type)) {
- logger.warn("Could not find \"" + type + "\" classification. Simulation Context type ignored.");
- continue;
- }
- tctex = SimulationContext.createType(type, mapstep.get(type)); // Creation of Simulation Context Types
- tctex.approve();
- }
- } catch (Exception error) {
- logger.warn("Error creating context types, reason:", error); // Should not happen
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Stand proxy for entities such as Study and Knowledge Element returned by Lucene-based searches.
- * This interface provides access to properties of searched entities which can be presented in a result search list
- * before loading the corresponding persistent objects from the database (reason for most properties to be returned as
- * strings).
- * One of these properties is the internal persistent identifier of the object represented by a proxy allowing the
- * user of this interface to load the object from the database.
- *
- * @see Database#selectStudiesWhere(Study.Properties...)
- * @see Database#selectKnowledgeElementsWhere(KnowledgeElement.Properties)
- * @see Database#selectStudy(int)
- * @see Database#selectKnowledgeElement(int)
- * @see Index
- * @see Index.ObjectProxy
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public interface Proxy {
-
- public String getAuthorName ();
-
-/**
- * Returns the internal persistent identifier of the object represented by this proxy. The returned identifier can be used
- * for selecting the corresponding persistent object from the database.
- * @return the internal persistent identifier of the object represented by this proxy.
- */
- public Integer getIndex ();
-
- public ProgressState getProgressState ();
-
-/**
- * Returns the external reference number of the object represented by this proxy. The returned reference is formated
- * according to the format defined in the configuration file of the application.
- * @return the external reference number of the object represented by this proxy.
- */
- public String getReference ();
-
- public String getTitle ();
-
-/**
- * Returns the type of the object represented by this proxy. Depending on the implementation, the returned type may or
- * may not be localized in the current locale of final user.
- * @return the type of the object represented by this proxy.
- */
- public String getType ();
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.Publication" table="doctag" lazy="false">
-
-<!-- Properties inherited Persistent
- -->
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
-<!-- Publication properties
- -->
- <!-- Document mydoc -->
- <many-to-one name="mydoc" column="doc" access="field" not-null="true" />
-
- <!-- ProjectElement owner -->
- <many-to-one name="owner" column="owner" access="field" not-null="true" />
-
- <!-- char isnew -->
- <property name="isnew" column="isnew" access="field" not-null="true" />
-
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Publication objects are the way to reference document versions from a Project Element.
- * As such, a Document version is added (or published) to a Project Element through a Publication object.
- * This publication is done by saving the Publication object produced when creating and versioning a Document from a given
- * Project Element Step (call of the saveAs() function).<br/>
- * <br/>
- * A Publication object is homogeneous to a reference to a Document version and belongs to one Project Element, this latter
- * being either a Study Scenario or a Study itself, depending on the Study Step to which the document is published.<br/>
- * <br/>
- * The document version referenced by a Publication object is the Value of the publication.
- *
- * @see Document
- * @see ProjectElement
- * @see Step
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.Session;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.NotApplicableException;
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-import org.splat.kernel.User;
-import org.splat.manox.Reader;
-import org.splat.manox.Toolbox;
-
-
-public class Publication extends Persistent {
-
-// Persistent fields
- private Document mydoc;
- private ProjectElement owner; // Either Study or Scenario, depending on the step involved by the publication
- private char isnew; // True if this references a document version new for the owner project element
-
-// Transient fields
- private Step mystep;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected Publication () {
-// ------------------------
- mystep = null;
- }
-// Internal constructors
- protected Publication (Document doc, ProjectElement publisher) {
-// --------------------------------------------------------------
- mydoc = doc;
- mystep = null;
- owner = publisher;
- isnew = 'Y';
- }
- protected Publication copy (ProjectElement publisher) {
-// -----------------------------------------------------
- Publication copy = new Publication();
- copy.mydoc = this.mydoc;
- copy.mystep = this.mystep; // May not be initialized yet
- copy.owner = publisher;
- copy.isnew = this.isnew;
- if (!copy.getOwnerStudy().equals(this.getOwnerStudy())) {
- copy.isnew = 'N'; // The referenced document is not new for the given study
- }
- return copy;
- }
-
-// ==============================================================================================================================
-// Member functions
-// ==============================================================================================================================
-
- public Relation addDependency (Publication to) {
-// ----------------------------------------------
- return this.addDependency(to.value());
- }
-
- public Relation addDependency (Document to) {
-// -------------------------------------------
- if (to == null) return null;
- else return mydoc.addRelation( new UsesRelation(mydoc, to) );
- }
-
-/**
- * Undo the out-date operation.
- *
- * @return true if the acceptance succeeds
- * @see #outdate()
- * @see DocumentRights#canAccept()
- */
- public boolean actualize () {
-// ---------------------------
- if (!this.isOutdated()) return false;
- isnew = 'Y';
- Database.getSession().update(this);
- return true;
- }
-
-/**
- * Promotes the document referenced by this publication from In-Check to Approved state, if not out-dated, and attaches the corresponding
- * time-stamp to the document.</br>
- * If the promoted document is the final result of the owner study, the study is itself is promoted as well.</br>
- * </br>
- * Limitation: the way this promotion is propagated to the study supposes that the study has only ONE final result document.
- *
- * @param adate the date of approval
- * @return true if the approval succeeded
- * @see #getProgressState()
- * @see DocumentRights#canApprove()
- * @see DocumentType#isStudyResult()
- * @see Study#getApproverOf(Publication)
- */
- public Timestamp approve (Date adate) {
-// -------------------------------------
- if (this.isOutdated()) return null;
- else if (mydoc.getProgressState() != ProgressState.inCHECK) return null; // This statement must conform to the corresponding right
-
- DocumentType type = mydoc.getType();
- Study owner = this.getOwnerStudy();
- ValidationCycle cycle = owner.getValidationCycleOf(type);
- User approver = cycle.getActor(ValidationStep.APPROVAL);
- Timestamp stamp = new Timestamp(ValidationStep.APPROVAL, mydoc, approver, adate);
- if (!mydoc.promote(stamp)) return null;
- if (type.isStudyResult() && owner.getProgressState() == ProgressState.inCHECK) owner.promote();
- return stamp; // Hoping that promotion of the study succeeded
- }
-
- public ConvertsRelation attach (String format) {
-// ----------------------------------------------
- return mydoc.attach(format);
- }
-
- public ConvertsRelation attach (String format, String description) {
-// ------------------------------------------------------------------
- return mydoc.attach(format, description);
- }
-
-/**
- * Demotes the document referenced by this publication to In-Work state, and removes the Promoter of the document, if exist.</br>
- * The In-Draft state is skipped (direct demotion to In-Work) if the validation cycle of the document does not include the review step.</br>
- * If the demoted document is the final result of the owner study, the study is itself is demoted as well.</br>
- * </br>
- * Limitation: the way this demotion is propagated to the study supposes that the study has only ONE final result document.
- *
- * @return true if the demotion succeeded
- * @see #getProgressState()
- * @see DocumentRights#canDemote()
- * @see DocumentType#isStudyResult()
- */
- public boolean demote () {
-// ------------------------
- DocumentType type = mydoc.getType();
- Study owner = this.getOwnerStudy();
-
- if (mydoc.getProgressState() == ProgressState.inCHECK) {
- ValidationCycle cycle = owner.getValidationCycleOf(type);
- if (cycle.enables(ValidationStep.REVIEW)) {
- if (!mydoc.demote()) return false;
- } else {
- if (!mydoc.demote()) return false;
- mydoc.demote();
- }
- } else
- if (mydoc.getProgressState() == ProgressState.inDRAFT) {
- if (!mydoc.demote()) return false;
- } else {
- return false;
- }
- if (type.isStudyResult() && owner.getProgressState() != ProgressState.inWORK) owner.demote();
- return true;
- }
-
-/**
- * Returns the study Step into which the document version referenced by this publication has been published.
- */
- public Step getInvolvedStep () {
-// ------------------------------
- if (mystep == null) {
- Step[] step = owner.getSteps();
- for (int i=0; i<step.length; i++) {
- mystep = step[i]; // The involved step necessarily exists
- if (mydoc.isInto(mystep)) break;
- }
- }
- return mystep;
- }
-
-/**
- * Returns either the Study Scenario or the Study itself to which this publication belongs, depending on the Study Step into
- * which the referenced document has been published.<br/>
- * If this publication belongs to a Study, the Project Element returned is the Study returned by getOwnerStudy().
- *
- * @return the Study Scenario or the Study to which this publication belongs to
- * @see #getOwnerStudy()
- */
- public ProjectElement getOwner () {
-// ---------------------------------
- return owner;
- }
-
- public Study getOwnerStudy () {
-// -----------------------------
- if (owner instanceof Study) return (Study)owner;
- else return ((Scenario)owner).getOwnerStudy();
- }
-
-/**
- * Returns the state of this published document.
- * It is the same than the state of the referenced document, unless this publication is out-of-date, in which case it is
- * In-Work state.
- *
- * @see #outdate()
- * @see #isOutdated()
- */
- public ProgressState getProgressState () {
-// ----------------------------------------
- if (this.isOutdated()) return ProgressState.inWORK; // Overrides the document state
- else return mydoc.getProgressState();
- }
-
- public List<Publication> getRelations (Class<? extends Relation> type) {
-// ----------------------------------------------------------------------
- if (type == null) return null;
-
- List<Publication> result = new ArrayList<Publication>();
- List<Relation> relist = mydoc.getRelations(type);
- for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
- Relation relation = i.next();
- Document relatedoc = (Document)relation.getTo();
- Publication related = owner.getPublication(relatedoc);
- if (related != null) {
- result.add(related);
- } else
- if (owner instanceof Scenario) { // The relation may cross steps belonging to a scenario and its owner study
- related = ((Scenario)owner).getOwnerStudy().getPublication(relatedoc);
- if (related != null) result.add(related);
- }
- }
- return result;
- }
-
- public File getSourceFile () {
-// ----------------------------
- return mydoc.getSourceFile();
- }
-
-/**
- * Undo the review operation by demoting the document referenced by this publication from In-Check to In-Draft state and
- * removing the Reviewer.</br>
- * If the demoted document is the final result of the owner study, the study is itself is demoted as well.</br>
- * </br>
- * Limitation: the way this demotion is propagated to the study supposes that the study has only ONE final result document.
- *
- * @return true if the demotion succeeded
- * @see #getProgressState()
- * @see #review()
- * @see DocumentRights#canInvalidate()
- * @see DocumentType#isStudyResult()
- */
- public boolean invalidate () {
-// ----------------------------
- if ( mydoc.getProgressState() != ProgressState.inCHECK ) return false;
- if (!mydoc.demote()) // Removes the reviewer if this document is In-Check
- return false;
- DocumentType type = this.value().getType();
- Study owner = this.getOwnerStudy();
- if (type.isStudyResult() && owner.getProgressState() == ProgressState.inCHECK) owner.demote();
- return true;
- }
-
- public boolean isNewForOwner () {
-// -------------------------------
- return (isnew == 'Y');
- }
-
- public boolean isOutdated () {
-// ----------------------------
- return (isnew == 'O');
- }
-
-/**
- * Promotes the document referenced by this publication from In-Work to In-Draft or In-Check state, if not out-dated, and attaches the corresponding
- * time-stamp to the document.</br>
- * The In-Draft state is skipped (direct promotion to In-Check) if the validation cycle of the document does not include the review step.</br>
- * Also, if the promoted document is the final result of the owner study, the study is itself promoted as well.</br>
- * This operation can be undo-ed by demote().</br>
- * </br>
- * Limitation: the way this promotion is propagated to the study supposes that the study has only ONE final result document.
- *
- * @return true if the promotion succeeded
- * @see #getProgressState()
- * @see #demote()
- * @see DocumentRights#canPromote()
- * @see DocumentType#isStudyResult()
- */
- public Timestamp promote (Date pdate) {
-// -------------------------------------
- if (this.isOutdated()) return null;
- else if (mydoc.getProgressState() != ProgressState.inWORK) return null; // This statement must conform to the corresponding right
- else {
- DocumentType type = mydoc.getType();
- Study owner = this.getOwnerStudy();
- ValidationCycle cycle = owner.getValidationCycleOf(type);
- User promoter = cycle.getActor(ValidationStep.PROMOTION);
- if (promoter == null) promoter = getInvolvedStep().getActor();
- if (promoter == null) promoter = owner.getAuthor();
- Timestamp stamp = new Timestamp(ValidationStep.PROMOTION, mydoc, promoter, pdate);
-
- if (!mydoc.promote(stamp) ) // Promotion to being reviewed
- return null;
- if (!cycle.enables(ValidationStep.REVIEW)) {
- mydoc.promote(null);
- }
- if (type.isStudyResult() && owner.getProgressState() == ProgressState.inWORK) owner.promote();
- return stamp; // Hoping that promotion of the study succeeded
- }
- }
-
- public void rename (String title) throws InvalidPropertyException {
-// ---------------------------------
- mydoc.rename(title);
- }
-
-/**
- * Promotes the document referenced by this publication from In-Draft to In-Check state, if not out-dated, and attaches the corresponding
- * time-stamp to the document.</br>
- * If the promoted document is the final result of the owner study, the study is itself is promoted as well.</br>
- * This operation can be undo-ed by invalidate().</br>
- * </br>
- * Limitation: the way this promotion is propagated to the study supposes that the study has only ONE final result document.
- *
- * @param rdate the date of review
- * @return true if the review succeeded
- * @see #getProgressState()
- * @see #invalidate()
- * @see DocumentRights#canReview()
- * @see DocumentType#isStudyResult()
- * @see Study#getReviewerOf(Publication)
- */
- public Timestamp review (Date rdate) {
-// ------------------------------------
- if (this.isOutdated()) return null;
- else if (mydoc.getProgressState() != ProgressState.inDRAFT) return null; // This statement must conform to the corresponding right
-
- DocumentType type = mydoc.getType();
- Study owner = this.getOwnerStudy();
- ValidationCycle cycle = owner.getValidationCycleOf(type);
- User reviewer = cycle.getActor(ValidationStep.REVIEW);
- Timestamp stamp = new Timestamp(ValidationStep.REVIEW, mydoc, reviewer, rdate);
- if (!mydoc.promote(stamp)) return null;
- if (type.isStudyResult() && owner.getProgressState() == ProgressState.inDRAFT) owner.promote();
- return stamp; // Hoping that promotion of the study succeeded
- }
-
-/**
- * Publishes the document referenced by this publication into the owner Project Element under the given revision number.<br/>
- * The state of the referenced document is supposed being automatically set according to the given revision number, but, due to the
- * versioning scheme, as it is not possible to differentiate In-Work and In-Draft states, this function has been deprecated (it is
- * currently used only for the need of integration of Microsoft Office which anyway has to be redesigned).
- * <br/>
- * Note: in the context of branch versioning, the given revision may be modified by an update of the branch name.
- *
- * @param newvers the required revision number
- * @throws FileNotFoundException If the referenced document is empty
- * @throws NotApplicableException If the referenced document is undefined
- * @deprecated
- */
- public void saveAs (Revision newvers) throws FileNotFoundException, NotApplicableException {
-// -------------------------------------
- if ( mydoc.isUndefined() ) throw new NotApplicableException("Cannot save a Publication object refering an undefined Document");
- if (!mydoc.getSourceFile().exists()) throw new FileNotFoundException();
-
- Database.getSession().save(this); // Must be done before updating the study in order to fix this final (rid-based) hascode
- mydoc.updateAs(newvers); // May change the branch name of given revision
- updateOwner();
- }
-
-/**
- * Publishes the document referenced by this publication into the owner Project Element under the given state,
- * the revision number of the document being automatically set accordingly.
- * If the given state is In-Draft and the document is final result of the owner study, this automatically promotes the study to In-Draft.
- *
- * @param state the required progress state
- * @throws FileNotFoundException If the referenced document is empty
- * @throws NotApplicableException If the referenced document is undefined
- */
- public void saveAs (ProgressState state) throws FileNotFoundException, NotApplicableException {
-// ----------------------------------------
- if ( mydoc.isUndefined() ) throw new NotApplicableException("Cannot save a Publication object refering an undefined Document");
- if (!mydoc.getSourceFile().exists()) throw new FileNotFoundException();
-
- if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
- Database.getSession().save(this); // Must be done before updating the study in order to fix this final (rid-based) hascode
- mydoc.updateAs(state);
- } else {
- DocumentType mytype = mydoc.getType();
- Study owner = this.getOwnerStudy();
- ValidationCycle cycle = owner.getValidationCycleOf(mytype);
- boolean review = cycle.enables(ValidationStep.REVIEW);
- if (!(state == ProgressState.inDRAFT && review) && !(state == ProgressState.inCHECK && !review)) {
- throw new NotApplicableException("Cannot save a result document in " + state.toString() + " state");
- }
- Database.getSession().save(this); // Must be done before updating the study in order to fix this final (rid-based) hascode
- mydoc.updateAs(ProgressState.inWORK);
-
- this.promote(mydoc.getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
- }
- updateOwner();
- }
-
-/**
- * Out-dates this publication and recursively all publications using this one.
- * Typically, a publication is out-dated when modifying a document to which it depends.
- *
- * @see #isOutdated()
- * @see #getProgressState()
- * @see #actualize()
- */
- public void outdate () {
-// ----------------------
- if (this.isOutdated()) return;
-
- List<Publication> relist = this.getRelations(UsedByRelation.class);
- for (Iterator<Publication> i = relist.iterator(); i.hasNext(); ) {
- i.next().outdate();
- }
- isnew = 'O';
- Database.getSession().update(this);
- }
-
-/**
- * Returns the document version referenced by this Publication.
- */
- public Document value () {
-// ------------------------
- return mydoc;
- }
-
-// ==============================================================================================================================
-// Private services
-// ==============================================================================================================================
-
- private void updateOwner () {
-// ---------------------------
- Session session = Database.getSession();
- Step step = this.getInvolvedStep();
-
-// Update of involved step
- Document previous = mydoc.getPreviousVersion();
- if (previous != null) {
- Publication oldoc = step.getDocument(previous.getIndex());
- boolean done = step.remove(oldoc); // Decrements the configuration tag count of document
- if (done) session.delete(oldoc); //WARNING: Potential problem because it's not automatically done as orphan object
- }
- step.add(this); // Increments the configuration tag count of document
-
-// Import the document properties and update of the study
- forwardProperties(mydoc.getSourceFile().asFile(), step);
- session.update(getOwner());
- }
-
- private void forwardProperties (java.io.File from, Step to) {
-// -----------------------------------------------------------
- Reader tool = Toolbox.getReader(from);
- if (tool == null) return; // No properties extractor available for this type of document
-
- SimulationContextType.Properties sprop = new SimulationContextType.Properties()
- .setStep(to.getStep())
- .setState(ProgressState.APPROVED);
- List<SimulationContextType> contype = SimulationContext.selectTypesWhere(sprop);
- if (contype.isEmpty()) return; // No approved property type configured at this step
-
- SimulationContext.Properties cprop = new SimulationContext.Properties();
- List<SimulationContext> context = to.getAllSimulationContexts();
-
- context = new ArrayList<SimulationContext>(context.size());
- context.addAll(to.getAllSimulationContexts());
- cprop.disableCheck();
- for (Iterator<SimulationContextType> i=contype.iterator(); i.hasNext(); ) {
- SimulationContextType property = i.next();
- for (Iterator<SimulationContext> j=context.iterator(); j.hasNext(); ) {
- SimulationContext existing = j.next();
- if (!existing.getType().equals(property)) continue;
- property = null; // Forget this property as it is already set
- break;
- }
- if (property != null) try {
- String value = tool.extractProperty(property.getName());
- if (value == null) continue; // Property not defined into the document
-
- cprop.setType(property).setValue(value);
- if (owner instanceof Study) ((Study)owner).addProjectContext(cprop); // Re-indexes knowledges and the study
- else to.addSimulationContext(cprop); // Re-indexes knowledges only
- } catch (Exception e) {
- break;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- - Mapping of the Relation class hierarchy.
- - The entire hierarchy is mapped to one single table using a String discriminator.
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
-<!-- Uses relation
- -->
- <subclass name="org.splat.som.UsesRelation" extends="org.splat.kernel.Relation" discriminator-value="uses">
- <many-to-one name="refer" column="refer" access="field" not-null="true" />
- </subclass>
-
-<!-- UsedBy relation
- -->
- <subclass name="org.splat.som.UsedByRelation" extends="org.splat.kernel.Relation" discriminator-value="usedby">
- <many-to-one name="refer" column="refer" access="field" not-null="true" />
- </subclass>
-
-<!-- Versions relation
- -->
- <subclass name="org.splat.som.VersionsRelation" extends="org.splat.kernel.Relation" discriminator-value="versions">
- <many-to-one name="refer" column="refer" access="field" not-null="true" />
- </subclass>
-
-<!-- Converts relation
- -->
- <subclass name="org.splat.som.ConvertsRelation" extends="org.splat.kernel.Relation" discriminator-value="converts">
- <many-to-one name="refer" column="refer" access="field" not-null="true" />
- </subclass>
-
-<!-- Contributor actor relation
- -->
- <subclass name="org.splat.som.ContributorRelation" extends="org.splat.kernel.Relation" discriminator-value="contributor">
- <many-to-one name="refer" column="refer" access="field" not-null="true" />
- </subclass>
-
-<!-- ValidationCycle relation
- -->
- <subclass name="org.splat.som.ValidationCycleRelation" extends="org.splat.kernel.Relation" discriminator-value="cycle">
- <many-to-one name="refer" column="refer" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />
- </subclass>
-
-<!-- Stamp relation
- -->
- <subclass name="org.splat.som.StampRelation" extends="org.splat.kernel.Relation" discriminator-value="stamp">
- <many-to-one name="refer" column="refer" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />
- </subclass>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class providing operations on version numbers such as incrementation and comparison.
- * Revision objects are created from and converted to strings in the internal format of version numbers (major.minor.branch).<br/>
- * Revision objects can also be created from and converted to strings in user-defined format, thanks to a formating tool
- * provided by the Format nested class.
- *
- * @see Revision.Format
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.nio.CharBuffer;
-import java.text.ParseException;
-
-
-public class Revision {
-
- private int major;
- private int minor;
- private int branch;
-
- public static class Format {
-// --------------------------
- private String pattern;
-
- public Format (String pattern) {
- this.pattern = pattern;
- }
-
- public String format (String verstring) {
- CharBuffer version = CharBuffer.allocate(pattern.length() + 2*2); // Maximum possible size
- char[] format = pattern.toCharArray();
- String[] vernum = verstring.split("\\x2E"); // version is suposed of the internal form (m.n.s)
- int branch = Integer.valueOf(vernum[2]);
-
- for (int i=0; i<format.length; i++) {
- char token = format[i];
- if (token == '%') {
- i += 1;
- token = format[i];
- if (token == 'M') {
- version.put(vernum[0]);
- } else if (token == 'm') {
- version.put(vernum[1]);
- } else if (token == 's') {
- version.put(vernum[2]);
- }
- } else if (token == '[') {
- if (branch == 0) while (format[i] != ']') i += 1;
- } else if (token == ']') {
- continue;
- } else {
- version.put(token);
- }
- }
- return new String(version.array(), 0, version.position());
- }
-
- public Revision parse (String verstring) throws ParseException {
- char[] format = pattern.toCharArray();
- char[] version = verstring.toCharArray();
- CharBuffer major = CharBuffer.allocate(4);
- CharBuffer minor = CharBuffer.allocate(4);
- CharBuffer branch = CharBuffer.allocate(4);
-
- int cursor = 0; // Index into version array
- for (int i=0; i<format.length; i++) { // The parsed string may not include the branch ID
- char token = format[i];
- if (token == '%') {
- i += 1;
- token = format[i];
- if (token == 'M') {
- while (cursor < version.length) {
- if (!Character.isDigit(version[cursor])) break;
- major.put(version[cursor]);
- cursor += 1;
- }
- } else if (token == 'm') {
- while (cursor < version.length) {
- if (!Character.isDigit(version[cursor])) break;
- minor.put(version[cursor]);
- cursor += 1;
- }
- } else if (token == 's') {
- while (cursor < version.length) {
- if (!Character.isDigit(version[cursor])) break;
- branch.put(version[cursor]);
- cursor += 1;
- }
- }
- } else if (token == '[' || token == ']') {
- continue;
- } else {
- if (version[cursor] != token) throw new ParseException(verstring, cursor);
- cursor += 1;
- }
- if (cursor >= version.length) break;
- }
- if (major.position() == 0) throw new ParseException(verstring, 0);
-
- String majnum = new String(major.array(), 0, major.position());
- if (minor.position() == 0) {
- return new Revision(Integer.valueOf(majnum), 0);
- } else {
- String minum = new String(minor.array(), 0, minor.position());
- if (branch.position() == 0) {
- return new Revision(Integer.valueOf(majnum), Integer.valueOf(minum));
- } else {
- String branum = new String(branch.array(), 0, branch.position());
- return new Revision(Integer.valueOf(majnum), Integer.valueOf(minum), branum);
- }
- }
- }
-
- public String toPattern () {
- return pattern;
- }
- }
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-/**
- * Constructs a Revision object from the internal representation of a version number (m.n.s).
- */
- public Revision (String value) {
-// ------------------------------
- String[] vernum = value.split("\\x2E");
- try {
- this.major = Integer.valueOf(vernum[0]);
- this.minor = Integer.valueOf(vernum[1]);
- this.branch = Integer.valueOf(vernum[2]);
- }
- catch (Exception e) { // NumberFormat or OutOfBound exception if value is not of the form m.n.s
- this.major = 0;
- this.minor = 0;
- this.branch = 0;
- }
- }
- public Revision () {
-// ------------------
- this.major = 0;
- this.minor = 0;
- this.branch = 0;
- }
- private Revision (int major, int minor) {
-// ---------------------------------------
- this.major = major;
- this.minor = minor;
- this.branch = 0;
- }
- private Revision (int major, int minor, String branch) {
-// ------------------------------------------------------
- this.major = major;
- this.minor = minor;
- this.branch = Integer.valueOf(branch);
- }
-
-// ==============================================================================================================================
-// Public member function
-// ==============================================================================================================================
-
- public Revision incrementAs (ProgressState state) {
-// -------------------------------------------------
- if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) minor += 1;
- else if (state == ProgressState.inCHECK) {
- major = major + 1;
- minor = 0;
- }
- return this;
- }
-
- public boolean isGraterThan (Revision base) {
-// ------------------------------------------
- if (this.major > base.major) return true;
- if (this.major < base.major) return false;
- return (this.minor > base.minor);
- }
-
- public boolean isMinor () {
-// -------------------------
- return (minor != 0);
- }
-
- public boolean isNull () {
-// ------------------------
- return (major+minor == 0);
- }
-/**
- * Sets the branch name of this revision.
- *
- * @param name the branch name or the internal representation of a version number (m.n.s)
- * @return this revision object
- */
- public Revision setBranch (String name) {
-// ---------------------------------------
- String[] vernum = name.split("\\x2E");
-
- branch = Integer.valueOf(vernum[vernum.length-1]);
- return this;
- }
-/**
- * Returns the internal representation of a version number (m.n.s) represented by this Revision object.
- */
- public String toString () {
-// -------------------------
- StringBuffer version = new StringBuffer();
- return version.append(major).append(".").append(minor).append(".").append(branch).toString();
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <union-subclass name="org.splat.som.Scenario" extends="org.splat.som.ProjectElement" table="scenario" lazy="false">
-
- <!-- Study owner -->
- <many-to-one name="owner" column="owner" insert="false" update="false" access="field" not-null="true" />
-
- <!-- int sid -->
- <property name="sid" column="sid" access="field" not-null="true" />
-
- <!-- User cuser -->
- <many-to-one name="cuser" column="cuser" access="field" />
-
- <!-- Set<KnowledgeElement> kelms -->
- <set name="kelms" inverse="true" lazy="false" order-by="`type`,`date` asc" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.som.KnowledgeElement" />
- </set>
-
- </union-subclass>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.IOException;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Vector;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.splat.kernel.Persistent;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.User;
-
-
-public class Scenario extends ProjectElement {
-
-// Persistent fields
- private Study owner;
- private int sid; // Identifier unique in the scope of owner study
- private User cuser; // User having checked-out the scenario, if done
- private Set<KnowledgeElement> kelms;
-
-// Transient fields
- private HashMap<Integer, List<KnowledgeElement>> known;
- private List<KnowledgeElement> knowl; // Copy of kelms excluding the internal Knowledge Element (ucase below)
- private KnowledgeElement ucase; // Internal Knowledge Element for accessing to all used simulation contexts
-
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private Study owner = null;
- private Scenario previous = null;
- private Step base = null;
- private String title = null;
- private String summary = null;
- private User manager = null;
- private Date date = null;
-
-// - Public services
-
- public void clear () {
- super.clear();
- owner = null;
- previous = null;
- base = null;
- title = null;
- summary = null;
- manager = null;
- date = null;
- }
-// - Protected services
-
- protected Step getBaseStep () {
- return base; // May be null
- }
- protected Scenario getInsertAfter () {
- return previous; // May be null
- }
- protected User getManager () {
- return manager;
- }
- protected Properties setOwnerStudy (Study owner)
- {
- this.owner = owner;
- return this;
- }
-// - Setters of Scenario properties
-
- public Properties setBaseStep (Step base) throws InvalidPropertyException
- {
- if (!(base.getOwner() instanceof Scenario)) throw new InvalidPropertyException("step");
- this.base = base;
- return this;
- }
- public Properties setDate (Date date)
- {
- this.date = date;
- return this;
- }
- public Properties setDescription (String summary)
- {
- if (summary.length() > 0) this.summary = summary;
- return this;
- }
- public Properties setInsertAfter (Scenario previous)
- {
- this.previous = previous;
- return this;
- }
- public Properties setManager (User user)
- {
- this.manager = user;
- return this;
- }
- public Properties setTitle (String title) throws InvalidPropertyException
- {
- if (title.length() == 0) throw new InvalidPropertyException("title");
- this.title = title;
- return this;
- }
-// - Global validity check
-
- public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (owner == null) throw new MissedPropertyException("owner");
- if (title == null) throw new MissedPropertyException("title");
- if (manager == null) throw new MissedPropertyException("manager");
- }
- }
-// Database fetch constructor
- protected Scenario () {
-// ---------------------
- known = null;
- knowl = null;
- ucase = null;
- }
-// Internal constructor
- protected Scenario (Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// -------------------------------------
- super(sprop); // Throws one of the above exception if not valid
- owner = sprop.owner;
- sid = 0;
- cuser = null;
- title = sprop.title; // Inherited attribute
- known = null;
- knowl = null; // Initialized when getting all Knowledge Elements
- ucase = null;
- kelms = new HashSet<KnowledgeElement>();
-
- manager = sprop.manager;
- if (!owner.isStaffedBy(manager)) throw new InvalidPropertyException("manager");
-
- credate = sprop.date; // Inherited attribute
- if (credate == null) {
- Calendar current = Calendar.getInstance();
- credate = current.getTime(); // Today
- }
- lasdate = credate; // Inherited attribute
-
- if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
-
- Scenario[] scene = owner.getScenarii();
- for (int i=0; i<scene.length; i++) if (scene[i].sid > this.sid) this.sid = scene[i].sid;
- sid += 1;
- if (sprop.base != null) copyContentsUpTo(sprop.base);
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public KnowledgeElement addKnowledgeElement (KnowledgeElement.Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// -------------------------------------------------------------------------------
- KnowledgeElement kelm = new KnowledgeElement(kprop.setOwnerScenario(this));
- Session session = Database.getSession();
- Transaction transax = session.getTransaction();
- try {
- session.save(kelm);
-// Update of my persistent data
- kelms.add(kelm);
-// Update of my transient data
- List<KnowledgeElement> known = getKnowledgeElementsOf(kelm.getType()); // Initializes this.known, if not yet done
- known.add(kelm);
- if (kelm.getType().equals("usecase")) {
- ucase = kelm;
- } else
- if (knowl != null) { // If null, knowl will be initialized when needed
- knowl.add(kelm);
- }
-// Update of the index of Knowledge Elements
- Database.getIndex().add(kelm);
- updateMe();
- return kelm;
- }
- catch (RuntimeException e) {
- if (transax != null && transax.isActive()) {
-// Second try-catch as the rollback could fail as well
- try {
- transax.rollback();
- } catch (HibernateException error) {
- Study.logger.debug("Error rolling back transaction", error);
- }
-// Throw again the first exception
- throw e;
- }
- return null;
- }
- catch (IOException error) {
- logger.error("Unable to index the knowedge element '" + kelm.getIndex() + "', reason:", error);
- return null;
- }
- }
-
- public void checkin () {
-// ----------------------
- cuser = null;
- lasdate = Calendar.getInstance().getTime();
- Database.getSession().update(this);
- }
-
- public boolean checkout (User user) {
-// -----------------------------------
- if (!owner.isStaffedBy(user)) return false;
-
- cuser = user;
- lasdate = Calendar.getInstance().getTime();
- Database.getSession().update(this);
- return true;
- }
-
- public List<KnowledgeElement> getAllKnowledgeElements () {
-// --------------------------------------------------------
- if (knowl == null) {
- knowl = new Vector<KnowledgeElement>(kelms.size());
- for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext(); ) {
- KnowledgeElement kelm = i.next();
- if (kelm.getType().equals("usecase")) ucase = kelm;
- else knowl.add(kelm);
- }
- }
- return Collections.unmodifiableList(knowl);
- }
-
- public KnowledgeElement getKnowledgeElement (int index) {
-// -------------------------------------------------------
- for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext();) {
- KnowledgeElement mykelm = i.next();
- if (mykelm.getIndex() == index) return mykelm;
- }
- return null;
- }
-
- public List<KnowledgeElement> getKnowledgeElementsOf (KnowledgeElementType type) {
-// --------------------------------------------------------------------------------
- if (kelms.isEmpty()) return new Vector<KnowledgeElement>(); // Smarter than returning null
- if (known == null) known = new HashMap<Integer, List<KnowledgeElement>>();
-
- int numtype = type.getIndex();
- List<KnowledgeElement> listype = known.get(numtype);
- if (listype == null) {
- listype = new Vector<KnowledgeElement>();
- for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext();) {
- KnowledgeElement kelm = i.next();
- if (kelm.getType().getIndex() == numtype) listype.add(kelm);
- }
- known.put(numtype, listype);
- }
- return listype; // No protection against this object corruption as it would not corrupt the database
- }
-
- public Study getOwnerStudy () {
-// -----------------------------
- return owner;
- }
-/**
- * Returns the local reference of this scenario. This reference is unique in the scope of the owner study.
- */
- public String getReference () {
-// -----------------------------
- return String.valueOf(sid);
- }
-
- public User getUser () {
-// ----------------------
- return cuser; // Null if the scenario has not been checked-out
- }
-
- public boolean removeKnowledgeElement (KnowledgeElement kelm) {
-// -------------------------------------------------------------
- KnowledgeElement torem = getKnowledgeElement(kelm.getIndex());
- if (torem == null) return false;
- boolean done = kelms.remove(torem);
- if (done) {
-// Update of my transient data
- List<KnowledgeElement> kelms = known.get(kelm.getType().getIndex());
- kelms.remove(torem);
- if (knowl != null) knowl.remove(torem);
- Database.getSession().update(this);
-//TODO: If the owner study is not private, remove the knowledge from the Lucene index
- return true;
- } else {
- return false;
- }
- }
-
- public boolean isCheckedout () {
-// ------------------------------
- return (cuser != null);
- }
-
- public boolean isEmpty () {
-// -------------------------
- Step[] mystep = this.getSteps();
- for (int i=0; i<mystep.length; i++) if (mystep[i].isStarted()) return false;
- return true;
- }
-
- public boolean isFinished () {
-// ----------------------------
- Step[] mystep = this.getSteps();
- boolean notempty = false; // If this is empty, this is not finished
- for (int i=0; i<mystep.length; i++) {
- if (!mystep[i].isStarted()) continue;
- if (!mystep[i].isFinished()) return false;
- notempty = true;
- }
- return notempty;
- }
-
-// ==============================================================================================================================
-// Protected member function
-// ==============================================================================================================================
-
- protected void updateMyIndex (Index lucin) throws IOException {
-// ------------------------------------------
- if (ucase == null) for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext(); ) {
- KnowledgeElement kelm = i.next();
- if (!kelm.getType().equals("usecase")) continue;
- ucase = kelm;
- break;
- }
- lucin.update(ucase);
- }
-
-// ==============================================================================================================================
-// Private services
-// ==============================================================================================================================
-
- private void copyContentsUpTo (Step lastep) {
-// -------------------------------------------
- Scenario base = (Scenario)lastep.getOwner();
- Step[] from = base.getSteps();
- Step[] to = this.getSteps();
- for (int i=0; i<from.length; i++) {
- Step step = from[i];
- if (step.getNumber() > lastep.getNumber()) break;
-
- List<Publication> docs = step.getAllDocuments();
- for (Iterator<Publication> j=docs.iterator(); j.hasNext(); ) {
- Publication doc = j.next().copy(this); // Creation of a new reference to the document
-// Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
- to[i].add(doc);
- }
- List<SimulationContext> ctex = step.getAllSimulationContexts();
- for (Iterator<SimulationContext> j=ctex.iterator(); j.hasNext(); ) {
- to[i].addSimulationContext(j.next());
- }
- }
- }
-
- private boolean updateMe () {
-// ---------------------------
- try {
- Database.getSession().update(this); // Update of relational base
- return true;
- }
- catch (Exception error) {
- logger.error("Unable to re-index the knowledge element '" + getIndex() + "', reason:", error);
- return false;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.SimulationContext" table="contelm">
-
-<!-- Properties inherited Persistent
- -->
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
-<!-- SimulationContext properties
- -->
- <!-- SimulationContextType type -->
- <many-to-one name="type" column="type" access="field" not-null="true" />
-
- <!-- int step -->
- <property name="step" column="step" access="field" not-null="true" />
-
- <!-- ProgressState state -->
- <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
-
- <!-- String value -->
- <property name="value" column="value" access="field" not-null="true" />
-
- <!-- int counter -->
- <property name="counter" column="counter" access="field" not-null="true" />
- </class>
-
-<!-- Class SimulationContextType
- -->
- <class name="org.splat.som.SimulationContextType" table="contype" lazy="false">
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
- <property name="name" column="name" access="field" not-null="true" />
- <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
- <property name="step" column="step" access="field" not-null="true" />
- </class>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.Serializable;
-import java.util.List;
-
-import org.hibernate.Session;
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-
-
-public class SimulationContext extends Persistent implements Serializable {
-
- private SimulationContextType type; // User extendable types
- private int step;
- private ProgressState state;
- private String value;
- private int counter;
-
- private static final long serialVersionUID = 422889133378471949L;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private SimulationContextType type = null;
- private ProjectSettings.Step step = null;
- private ProgressState state = null;
- private String value = null;
-
-// - Public services
-
- public void clear () {
- super.clear();
- type = null;
- step = null;
- state = null;
- value = null;
- }
- protected ProgressState getProgressState () {
- return state;
- }
- public SimulationContextType getType () {
- return type;
- }
- public String getValue () {
- return value;
- }
-
-// - Setters of SimulationContext properties
-
- public Properties setState (ProgressState state) throws InvalidPropertyException
- {
- if (state != ProgressState.inCHECK && state != ProgressState.APPROVED) {
- throw new InvalidPropertyException("state");
- }
- this.state = state;
- return this;
- }
- protected Properties setStep (ProjectSettings.Step step) throws InvalidPropertyException
- {
- this.step = step;
- return this;
- }
- public Properties setValue (String value) throws InvalidPropertyException
- {
- if (value.length() == 0) throw new InvalidPropertyException("value");
- this.value = value;
- return this;
- }
- public Properties setType (SimulationContextType type)
- {
- this.type = type;
- return this;
- }
-// - Global validity check
-
- public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (type == null) throw new MissedPropertyException("type");
- if (step == null) throw new MissedPropertyException("step");
- if (value == null) throw new MissedPropertyException("value");
- if (!type.isAttachedTo(step)) throw new InvalidPropertyException("step");
- }
- }
-// Database fetch constructor
- protected SimulationContext () {
- }
-// Internal constructor
- protected SimulationContext (Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
- super(kprop); // Throws one of the above exception if not valid
- type = kprop.type;
- step = kprop.step.getNumber();
- value = kprop.value;
- counter = 0;
- state = kprop.state;
- if (state == null) state = ProgressState.inCHECK;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean approve () {
-// -------------------------
- if (state != ProgressState.inCHECK) return false;
- this.state = ProgressState.APPROVED; // The type name is supposed being localized
- Database.getSession().update(this);
- return true;
- }
-
- public boolean equals (SimulationContext given) {
-// -----------------------------------------------
- if (isSaved()) return (this.getIndex() == given.getIndex());
- if (!this.getType().getName().equals(given.getType().getName())) return false;
- if (this.getValue().equals(given.getValue())) return true;
- return false;
- }
-
- public String getValue () {
-// -------------------------
- return value;
- }
-
- public ProgressState getProgressState () {
-// ----------------------------------------
- return state;
- }
-
- public SimulationContextType getType () {
-// ---------------------------------------
- return type;
- }
-
- public boolean isInto (Step container) {
-// --------------------------------------
- return (step == container.getNumber());
- }
-
- public boolean isShared () {
-// --------------------------
- return (counter > 1);
- }
-
-// ==============================================================================================================================
-// Public services
-// ==============================================================================================================================
-
- public static SimulationContextType createType (String name, ProjectSettings.Step step) throws InvalidPropertyException, RuntimeException {
-// ---------------------------------------------------------------------------------------
-//TODO: Check for duplicate definition
- SimulationContextType type = new SimulationContextType(name, step);
- Session session = Database.getSession();
- session.save(type);
-
- return type;
- }
-
- @SuppressWarnings("unchecked")
- public static List<SimulationContextType> selectAllTypes () {
-// -----------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContextType"); // Useless to order by names as the result mixes localized and non localized types
- query = query.append(" order by step asc");
- return Database.getSession().createQuery(query.toString()).list();
- }
-
- @SuppressWarnings("unchecked")
- public static List<SimulationContextType> selectTypesOf (ProjectSettings.Step... step) {
-// --------------------------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContextType where step='").append(step[0].getNumber()).append("'");
- for (int i=1; i<step.length; i++) { // Useless to order as the result mixes localized and non localized types
- query = query.append(" or step='").append(step[i].getNumber()).append("'");
- }
- query = query.append(" order by step asc");
- return Database.getSession().createQuery(query.toString()).list();
- }
-
- @SuppressWarnings("unchecked")
- public static List<SimulationContextType> selectTypesWhere (SimulationContextType.Properties sprop) {
-// ---------------------------------------------------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContextType");
- String separator = " where";
- ProjectSettings.Step step = sprop.getStep();
- ProgressState state = sprop.getProgressState();
- String order = " order by step asc";
-
- if (step != null) {
- query = query.append(separator).append(" step='").append(step.getNumber()).append("'");
- separator = " and";
- order = " order by state desc"; // APPROVED (upper case A) is grater than inCHECK (lower case i)
- }
- if (state != null) {
- query = query.append(separator).append(" state='").append(state.toString()).append("'");
-// separator = " and";
- if (step != null) {
- if (state != ProgressState.APPROVED) order = " order by name asc";
- else order = ""; // Approved types are localized
- }
- }
- query = query.append(order);
- return Database.getSession().createQuery(query.toString()).list();
- }
-
- public static SimulationContextType selectType (String name) {
-// ------------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContextType where name='").append(name).append("'");
- return (SimulationContextType)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
- public static SimulationContextType selectType (int index) {
-// ----------------------------------------------------------
- StringBuffer query = new StringBuffer("from SimulationContextType where rid='").append(index).append("'");
- return (SimulationContextType)Database.getSession().createQuery(query.toString()).uniqueResult();
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected void hold () {
-// ----------------------
- counter += 1;
- if (this.isSaved()) Database.getSession().update(this);
- }
-
- protected void release () {
-// -------------------------
- counter -= 1;
- if (this.isSaved()) Database.getSession().update(this);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.Serializable;
-
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.Persistent;
-
-
-public class SimulationContextType extends Persistent implements Serializable {
-
-// Persistent fields
- private String name;
- private ProgressState state;
- private int step;
-
-// Required by the serialization
- private static final long serialVersionUID = 4819425038576161242L;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Search properties class
- public static class Properties {
-// ------------------------------
- private ProgressState state = null;
- private ProjectSettings.Step step = null;
-
- protected ProgressState getProgressState () {
- return state;
- }
- protected ProjectSettings.Step getStep () {
- return step;
- }
- public Properties setState (ProgressState state) {
- this.state = state;
- return this;
- }
- public Properties setStep (ProjectSettings.Step step) {
- this.step = step;
- return this;
- }
- }
-// Database fetch constructor
- protected SimulationContextType () {
- }
-// Initialization constructor
- protected SimulationContextType (String name, ProjectSettings.Step step) throws InvalidPropertyException {
-// ------------------------------------------------------------------------
- super();
- this.name = name;
- this.state = ProgressState.inCHECK;
- this.step = step.getNumber();
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean approve () {
-// -------------------------
- if (state != ProgressState.inCHECK) return false;
- this.state = ProgressState.APPROVED; // The type name is supposed being localized
- Database.getSession().update(this);
- return true;
- }
-
- public boolean equals(Object entity) {
-// ------------------------------------
- if (entity == null) return false;
- if (entity instanceof String) {
- return this.name.equals((String)entity); // Names are unique
- } else
- if (entity instanceof SimulationContextType) {
- SimulationContextType object = (SimulationContextType)entity;
- int he = object.getIndex();
- int me = this.getIndex();
- if (me*he != 0) return (he == me);
- else return this.getName().equals(object.getName());
- } else {
- return false;
- }
- }
-
- public ProjectSettings.Step getAttachedStep () {
-// ----------------------------------------------
- return ProjectSettings.getStep(step);
- }
-
- public String getName () {
-// ------------------------
- return name;
- }
-
- public boolean isAttachedTo (ProjectSettings.Step step) {
-// -------------------------------------------------------
- if (this.step == step.getNumber()) return true;
- return false;
- }
-
- public boolean isApproved () {
-// ----------------------------
- return (state == ProgressState.APPROVED);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-
-
-public class StampRelation extends Relation {
-
- private Timestamp refer;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected StampRelation () {
- }
-// Internal constructor
- protected StampRelation (Document from, Timestamp to) {
-// -----------------------------------------------------
- super(from);
- this.refer = to;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Timestamp getTo () {
-// -------------------------
- return refer;
- }
-
- public ValidationStep getStampType () {
-// -------------------------------------
- return refer.getType();
- }
-
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (Timestamp)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-import java.util.Iterator;
-
-import org.hibernate.Session;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MismatchException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.NotApplicableException;
-import org.splat.kernel.Relation;
-import org.splat.kernel.User;
-import org.splat.som.Database;
-
-
-public class Step {
-
- private ProjectSettings.Step step;
- private ProjectElement owner;
- private List<SimulationContext> contex;
- private List<Publication> docums;
- private User actor; // Actor involved in operations on published documents and requiring a time-stamp
-
-// ==============================================================================================================================
-// Constructor
-// ==============================================================================================================================
-
- protected Step (ProjectSettings.Step step, ProjectElement owner) {
-// ----------------------------------------------------------------
- this.step = step;
- this.owner = owner;
- this.contex = new Vector<SimulationContext>();
- this.docums = new Vector<Publication>();
- this.actor = null;
-
-// Filtering of Simulation contexts, if exist
- for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
- SimulationContext adoc = i.next();
- if (!adoc.isInto(this)) continue;
- this.contex.add(adoc);
- }
-// Filtering of Documents, if exist
- for (Iterator<Publication> i=owner.PublicationIterator(); i.hasNext();) {
- Publication mydoc = i.next();
- if (!mydoc.value().isInto(this)) continue;
- this.docums.add(mydoc);
- }
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Publication createDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException {
-// -------------------------------------------------------------
- Document newdoc = new Document(dprop.setOwner(owner).setStep(step));
-
-// Creation of the save directory
- File wdir = newdoc.getSaveDirectory();
- if (!wdir.exists()) if (!wdir.mkdirs()) throw new IOException("Cannot create the repository vault directory");
-
-// Identification and save
- newdoc.buildReferenceFrom(getOwnerStudy());
- Database.getSession().save(newdoc);
-
- return new Publication(newdoc, owner);
- }
-
- public Publication assignDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, NotApplicableException {
-// -------------------------------------------------------------
- String refid = dprop.getReference();
- if (refid == null) return null;
-
- Document slot = Database.selectDocument(refid, new Revision().toString());
- if ( slot == null ) return null;
- if (!slot.isUndefined()) return null; // Should not happen
-
- slot.initialize(dprop.setOwner(getOwnerStudy()));
- return new Publication(slot, owner);
- }
-
- public Publication versionDocument (Publication base) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
-// -----------------------------------------------------
- return versionDocument(base, new Document.Properties());
- }
-
- public Publication versionDocument (Publication base, String reason) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
-// --------------------------------------------------------------------
- return versionDocument(base, new Document.Properties().setDescription(reason));
- }
-
- public Publication versionDocument (Publication base, Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
-// --------------------------------------------------------------------------------
- Document previous = base.value();
-
- dprop.setDocument(previous); // Initializes the Step property
- if (dprop.getStep().getNumber() != this.step.getNumber()) throw new MismatchException();
-
- if (dprop.getAuthor() == null) dprop.setAuthor(previous.getAuthor());
- String summary = dprop.getDescription();
-
-// Creation of the document
- Document newdoc = new Document(dprop.setOwner(owner).setStep(step));
- newdoc.buildReferenceFrom(getOwner(), previous);
- Database.getSession().save(newdoc);
-
-// Versioning
- if (summary == null) newdoc.addRelation( new VersionsRelation(newdoc, previous) );
- else newdoc.addRelation( new VersionsRelation(newdoc, previous, summary) );
-
-// Update of usedby relations, if exist
- List<Relation> relist = previous.getRelations(UsedByRelation.class);
- Study scope = getOwnerStudy();
- for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
- UsedByRelation relation = (UsedByRelation)i.next();
- Document relatedoc = relation.getTo();
- if (scope.shares(relatedoc)) relatedoc.addRelation( new UsesRelation(relatedoc, newdoc) );
- else relation.moveTo(newdoc);
- }
- return new Publication(newdoc, owner);
- }
-
- public SimulationContext addSimulationContext (SimulationContext.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
-// ----------------------------------------------------------------------------------
- SimulationContext context = new SimulationContext(dprop.setStep(step));
- return addSimulationContext(context);
- }
-
- public SimulationContext addSimulationContext (SimulationContext context) {
-// -------------------------------------------------------------------------
- context.hold(); // Increments the reference count of simulation context
- if (owner.isSaved()) try {
- Session session = Database.getSession();
- Index lucin = Database.getIndex();
-
- if (!context.isSaved()) session.save(context);
- owner.add(context);
- contex.add(context); // The context is also referenced from this (transient) Step
- session.update(owner);
- updateKnowledgeElementsIndex(lucin);
- }
- catch (Exception error) {
- return null;
- }
- else { // Happens when copying a scenario
- owner.add(context);
- contex.add(context); // The context is also referenced from this (transient) Step
-// In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
- }
- return context;
- }
-
- public User getActor () {
-// -----------------------
- return actor;
- }
-
- public List<Publication> getAllDocuments () {
-// -------------------------------------------
- return Collections.unmodifiableList(docums);
- }
-
- public List<SimulationContext> getAllSimulationContexts () {
-// ----------------------------------------------------------
- return Collections.unmodifiableList(contex);
- }
-
- public Publication getDocument (int index) {
-// ------------------------------------------
- for (Iterator<Publication> i=docums.iterator(); i.hasNext();) {
- Publication found = i.next(); // In a given study step,
- if (found.value().getIndex() == index) return found; // there is only one publication of a given document
- }
- return null;
- }
-
- public int getNumber () {
-// -----------------------
- return step.getNumber();
- }
-
- public ProjectElement getOwner () {
-// ---------------------------------
- return owner; // May be a Study or a Scenario
- }
-
- public Study getOwnerStudy () {
-// -----------------------------
- if (owner instanceof Study) return (Study)owner;
- else return ((Scenario)owner).getOwnerStudy();
- }
-
- public String getPath () {
-// ------------------------
- return step.getPath();
- }
-
- public List<Publication> getResultDocuments () {
-// ----------------------------------------------
- List<Publication> result = new Vector<Publication>();
-
- if (!docums.isEmpty()) for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
- Publication content = i.next();
- DocumentType type = content.value().getType();
- if (!type.isResultOf(this.getStep())) continue;
- result.add(content);
- }
- return result;
- }
-
- public ProjectSettings.Step getStep () {
-// --------------------------------------
- return step;
- }
-
- public SimulationContext getSimulationContext (int index) {
-// ---------------------------------------------------------
- for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
- SimulationContext myctex = i.next();
- if (myctex.getIndex() == index) return myctex;
- }
- return null;
- }
-
- public List<SimulationContext> getSimulationContext (SimulationContextType type) {
-// --------------------------------------------------------------------------------
- Vector<SimulationContext> result = new Vector<SimulationContext>();
-
- for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
- SimulationContext myctex = i.next();
- if (myctex.getType().equals(type)) result.add(myctex);
- }
- return result;
- }
-
- public List<DocumentType> getValidDocumentTypes () {
-// --------------------------------------------------
- return Document.selectTypesOf(step);
- }
-
- public boolean isStarted () {
-// ---------------------------
- if (!step.mayContain(KnowledgeElement.class)) return !docums.isEmpty();
-
- List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
- if (kelm.isEmpty() && docums.isEmpty()) return false;
- return true;
- }
-
- public boolean isFinished () {
-// ----------------------------
- if (!step.mayContain(KnowledgeElement.class)) { // Check if all result documents are approved
- if (docums.isEmpty()) return false;
- boolean result = false;
- for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
- Document content = i.next().value();
- DocumentType type = content.getType();
- if (!type.isResultOf(this.getStep())) continue;
- if (content.getProgressState() == ProgressState.EXTERN) continue;
- result = true; // There is at least 1 non external result document
- if (content.getProgressState() != ProgressState.APPROVED) return false;
- }
- return result;
- }
- else { // Check if all existing knowledges are approved
- List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
- if (kelm.isEmpty()) return false;
- for (Iterator<KnowledgeElement> i=kelm.iterator(); i.hasNext(); ) {
- KnowledgeElement content = i.next();
- if (content.getProgressState() != ProgressState.APPROVED) return false;
- }
- return true;
- }
- }
-
- public boolean mayContain (@SuppressWarnings("rawtypes") Class type) {
-// --------------------------------------------------------------------
- return step.mayContain(type);
- }
-
- public boolean removeDocument (Publication doctag) {
-// --------------------------------------------------
- Document value = doctag.value();
- Publication torem = getDocument(value.getIndex());
- Session session = Database.getSession();
-
- if (torem == null) return false;
-
- this.remove(torem);
- session.update(owner);
- if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
- Set<Relation> links = value.getAllRelations();
- List<Document> using = new Vector<Document>();
- for (Iterator<Relation> i=links.iterator(); i.hasNext(); ) {
- Relation link = i.next();
- if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
- session.delete(link.getTo()); // The corresponding physical file is not removed from the vault
- } else
- if (link.getClass().equals(UsesRelation.class)) { // Document dependency
- using.add((Document)link.getTo());
- }
- }
- for (Iterator<Document> i=using.iterator(); i.hasNext(); ) {
- i.next().removeRelation(UsedByRelation.class, value);
- }
- session.delete(value); // The corresponding physical file is not removed from the vault
- }
- return true;
- }
-
- public boolean removeSimulationContext (SimulationContext context) {
-// ------------------------------------------------------------------
- SimulationContext torem = getSimulationContext(context.getIndex());
- Session session = Database.getSession();
-
- if (torem == null) return false;
- if (!owner.remove(torem)) return false;
-
- contex.remove(torem);
- session.update(owner);
- if (torem.isShared()) {
- torem.release();
- session.update(torem);
- } else {
- session.delete(torem);
- }
- return true;
- }
-
- public void setActor (User user) {
-// --------------------------------
- actor = user;
- }
-// ==============================================================================================================================
-// Protected member functions
-// ==============================================================================================================================
-
- protected boolean add (Publication newdoc) {
-// ------------------------------------------
- if (!owner.add(newdoc)) return false; // Updates the study in memory
- docums.add(0, newdoc); // Updates this step
- newdoc.value().hold(); // Increments the configuration tag count of document
-// If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
-// database (it will be saved later by cascading the update of owner scenario).
- return true;
- }
-
- protected boolean remove (Publication oldoc) {
-// --------------------------------------------
- if (!owner.remove(oldoc)) return false; // Updates the study in memory
- docums.remove(oldoc); // Updates this step
- oldoc.value().release(); // Decrements the configuration tag count of document
-// The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
- return true;
- }
-
-// ==============================================================================================================================
-// Private services
-// ==============================================================================================================================
-
- private void updateKnowledgeElementsIndex(Index lucin) {
-// ------------------------------------------------------
- Scenario[] scenarii;
- if (owner instanceof Scenario) {
- scenarii = new Scenario[1];
- scenarii[0] = (Scenario)owner;
- } else {
- scenarii = getOwnerStudy().getScenarii();
- }
- try {
- for (int i=0; i<scenarii.length; i++) {
- Scenario scene = scenarii[i];
- List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
- for (Iterator<KnowledgeElement> j=knelm.iterator(); j.hasNext(); ) {
- KnowledgeElement kelm = j.next();
- lucin.update(kelm);
- }
- scene.updateMyIndex(lucin);
- }
- }
- catch (Exception error) {
-// logger.error("Unable to re-index Knowledge Elements, reason:", error);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class defining the default rights related to operations on study steps.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-//TODO: Review this rights according to the state of the owner study.
-
-import org.splat.kernel.User;
-
-
-public class StepRights {
-
- private User user;
- private Step operand;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
- public StepRights (User user, Step step) {
-// ----------------------------------------
- this.user = user;
- this.operand = step;
- }
- public StepRights (Step step) {
-// -----------------------------
- this.user = step.getOwner().getAuthor();
- this.operand = step;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
-/**
- * Checks if the user has right to add a comment attached to the selected step.
- * All actors of the study have such right, including the author, contributors, reviewers and approvers.
- *
- * @return true if the user has right to add a comment.
- */
- public boolean canAddComment () {
-// -------------------------------
- Study owner = operand.getOwnerStudy();
- return (owner.getAuthor().equals(user) || owner.hasActor(user));
- }
-
-/**
- * Checks if the user has right to create or import a document into the selected step.
- * Only the author and contributors have such right, providing that the study step is enabled for writing.
- *
- * @return true if the user has right to create or import a document.
- */
- public boolean canCreateDocument () {
-// -----------------------------------
- if (!isEnabled()) return false;
- return operand.getOwnerStudy().isStaffedBy(user);
- }
-
-/**
- * Checks if the user has right to enter a knowledge into the selected step.
- * Only the author and contributors have such right.
- *
- * @return true if the user has right to enter a knowledge.
- */
- public boolean canCreateKnowledge () {
-// ------------------------------------
- return operand.getOwnerStudy().isStaffedBy(user);
- }
-
-/**
- * Checks if the user has right to edit the simulation contexts attached to the selected step.
- * All actors of the study have such right, including the author, contributors, reviewers and approvers.
- *
- * @return true if the user has right to edit the simulation contexts.
- */
- public boolean canEditSimulationContext () {
-// ------------------------------------------
- Study owner = operand.getOwnerStudy();
- return (owner.getAuthor().equals(user) || owner.hasActor(user));
- }
-
-/**
- * Checks if the selected step is enabled for writing.
- * A step may be disabled for writing, or locked, following a check-out of the owner scenario.
- *
- * @return true if the step is enabled for writing.
- */
- public boolean isEnabled () {
-// ---------------------------
- ProjectElement owner = operand.getOwner();
-
- if (owner instanceof Scenario) {
- Scenario scene = (Scenario)owner;
- if (scene.isCheckedout()) return false;
- }
- return true;
- }
-
-// ==============================================================================================================================
-// Getters
-// ==============================================================================================================================
-
- public Step getOperand () {
-// -------------------------
- return operand;
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <typedef name="ProgressState" class="org.splat.kernel.GenericEnumType">
- <param name="enumClassName">org.splat.som.ProgressState</param>
- </typedef>
-
- <typedef name="Visibility" class="org.splat.kernel.GenericEnumType">
- <param name="enumClassName">org.splat.som.Visibility</param>
- </typedef>
-
- <union-subclass name="org.splat.som.Study" extends="org.splat.som.ProjectElement" table="study" lazy="false">
-
- <!-- String sid -->
- <property name="sid" column="sid" access="field" not-null="true" />
-
- <!-- int docount -->
- <property name="docount" column="docount" access="field" not-null="true" />
-
- <!-- ProgressState state -->
- <property name="state" type="ProgressState" column="state" access="field" not-null="true" />
-
- <!-- Visibility visibility -->
- <property name="visibility" type="Visibility" column="area" access="field" not-null="true" />
-
- <!-- List<Scenario> scenarii -->
- <list name="scenarii" lazy="false" cascade="delete-orphan" access="field">
- <key column="owner" not-null="true" />
- <list-index column="scendex"/>
- <one-to-many class="org.splat.som.Scenario" />
- </list>
-
- <!-- String version -->
- <property name="version" column="version" access="field" not-null="true" />
-
- <!-- int history -->
- <property name="history" column="history" access="field" not-null="true" />
-
- </union-subclass>
-
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.LinkedList;
-import java.util.Set;
-import java.util.Vector;
-
-import org.hibernate.Session;
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-import org.splat.kernel.User;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.UserDirectory;
-
-
-public class Study extends ProjectElement {
-
-// Persistent fields
- private String sid; // External unique reference in a format conform to the configuration pattern
- private int docount; // Total number of documents of this study, including versions
- private ProgressState state;
- private Visibility visibility;
- private List<Scenario> scenarii;
- private String version;
- private int history; // Number of studies versioning this one, if any
-
-// Transient fields
- private List<User> contributor; // Shortcut to contributors
- private HashMap<String,ValidationCycle> validactor; // Shortcut to validation cycles
- private Set<User> actor; // Summary of above actors
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- private String sid = null; // Search criterion only
- private String title = null;
- private String summary = null;
- private User manager = null;
- private User actor = null; // Search criterion only
- private Visibility visibility = null; // Search criterion only
- private ProgressState state = null; // Search criterion only
- private Date date = null;
- private List<SimulationContext> context = new Vector<SimulationContext>(); // Search criterion only
-
-// - Public services
-
- public void clear () {
- super.clear();
- sid = null;
- title = null;
- summary = null;
- manager = null;
- actor = null;
- visibility = null;
- state = null;
- date = null;
- context = new Vector<SimulationContext>(); // as clear() may generate side effects
- }
- public Properties copy () {
- Properties copy = new Properties();
- copy.sid = this.sid;
- copy.title = this.title;
- copy.summary = this.summary;
- copy.manager = this.manager;
- copy.actor = this.actor;
- copy.visibility = this.visibility;
- copy.state = this.state;
- copy.date = this.date;
- copy.context = this.context;
- return copy;
- }
-// - Protected services
-
- protected User getActor () {
- return actor;
- }
- protected User getManager () {
- return manager;
- }
- protected ProgressState getProgressState () {
- return state;
- }
- protected String getReference () {
- return sid;
- }
- protected List<SimulationContext> getSimulationContexts () {
- return context;
- }
- protected String getTitle () {
- return title;
- }
- protected Visibility getVisibility () {
- return visibility;
- }
-// - Property setters
-
-// For building a search query
- public Properties setActor (User actor)
- {
- this.actor = actor;
- return this;
- }
- public Properties setDate (Date date)
- {
- this.date = date;
- return this;
- }
- public Properties setDescription (String summary)
- {
- if (summary.length() > 0) this.summary = summary;
- return this;
- }
- public Properties setManager (User user)
- {
- this.manager = user;
- return this;
- }
-// For building a search query
- public Properties setReference (String sid) throws InvalidPropertyException
- {
- if (sid.length() == 0) throw new InvalidPropertyException("reference");
- this.sid = sid;
- return this;
- }
-// For building a search query
- public Properties setSimulationContexts (List<SimulationContext> context) {
- this.context = context;
- return this;
- }
-// For building a search query
- public Properties setState (ProgressState state)
- {
- this.state = state;
- return this;
- }
- public Properties setTitle (String title) throws InvalidPropertyException
- {
- if (title.length() == 0) throw new InvalidPropertyException("title");
- this.title = title;
- return this;
- }
-// For building a search query
- public Properties setVisibility (Visibility area)
- {
- this.visibility = area;
- return this;
- }
-// - Global validity check
-
- public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
- {
- if (title == null) throw new MissedPropertyException("title");
- if (manager == null) throw new MissedPropertyException("manager");
- }
- }
-// Database fetch constructor
- protected Study () {
-// ------------------
- contributor = null;
- validactor = null;
- actor = null;
- }
-// Internal constructor
- protected Study (Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// ----------------------------------
- super(sprop); // Throws one of the above exception if not valid
- sid = ProjectSettings.getReferencePattern(); // Reset after save
- title = sprop.title; // Inherited attribute
- manager = sprop.manager;
- docount = 0;
- history = 0;
- scenarii = new LinkedList<Scenario>();
- visibility = Visibility.PRIVATE;
- state = ProgressState.inWORK;
-
- credate = sprop.date; // Inherited attribute
- if (credate == null) {
- Calendar current = Calendar.getInstance();
- credate = current.getTime(); // Today
- }
- lasdate = credate; // Inherited attribute
- version = new Revision().incrementAs(state).toString();
-
- if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
-
- contributor = null;
- validactor = null;
- actor = null;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean addContributor (User user) {
-// -----------------------------------------
- if (contributor == null) this.setShortCuts(); // Initializes contributor
- for (Iterator<User> i=contributor.iterator(); i.hasNext(); ) {
- User present = i.next();
- if ( present.equals(user) ) return false;
- }
- boolean absent = actor.add(user); // User may already be a reviewer or an approver
-
- this.addRelation( new ContributorRelation(this, user) );
- if (absent) updateMe(); // Else, useless to re-index the study
- contributor.add(user);
- return true;
- }
-
- public SimulationContext addProjectContext (SimulationContext.Properties cprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
-// -------------------------------------------------------------------------------
- SimulationContext added = this.getFirstStep().addSimulationContext(cprop);
- updateMe();
- return added;
- }
-
- public SimulationContext addProjectContext (SimulationContext context) {
-// ----------------------------------------------------------------------
- SimulationContext added = this.getFirstStep().addSimulationContext(context);
- updateMe();
- return added;
- }
-
- public Scenario addScenario (Scenario.Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
-// -------------------------------------------------------
- if (sprop.getManager() == null) sprop.setManager(this.manager);
-
- Scenario scenario = new Scenario(sprop.setOwnerStudy(this));
- Scenario previous = sprop.getInsertAfter();
- Session session = Database.getSession();
-
- if (previous == null) {
- scenarii.add(scenario);
- } else {
- scenarii.add(scenarii.indexOf(previous)+1, scenario);
- }
- session.update(this); // No need to update the Lucene index
- session.save(scenario); // Must be done after updating this study because of the back reference to the study
- if (sprop.getBaseStep() != null) {
-// No need to update the Knowledge Element index as Knowledge Elements are not copied
- scenario.refresh(); // Because saving the scenario changes the hashcode of copied Publications
- }
- KnowledgeElementType ucase = KnowledgeElement.selectType("usecase");
- KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
- User admin = UserDirectory.selectUser(1); // First user created when creating the database
- kprop.setType(ucase)
- .setTitle(this.getTitle())
- .setValue(scenario.getTitle())
- .setAuthor(admin); // Internal Knowledge Element required by the validation process of knowledges
- scenario.addKnowledgeElement(kprop);
- return scenario;
- }
-
-/**
- * Returns all actors of this study other than the author, including contributors, reviewers and approvers.
- *
- * @return the actors of this study
- * @see #hasActor(User)
- */
- public Set<User> getActors () {
-// -----------------------------
- if (actor == null) setShortCuts();
- return Collections.unmodifiableSet(actor);
- }
-
- public List<User> getContributors () {
-// ------------------------------------
- if (contributor == null) setShortCuts();
- return Collections.unmodifiableList(contributor); // May be empty
- }
-
- public ProgressState getProgressState () {
-// ----------------------------------------
- return state;
- }
-
-/**
- * Returns the global unique reference of this study.
- * The study reference is common to all versions of the study (versioning a study does not change its reference).
- * The form of this study reference is defined in the configuration of the application server - see the SOM XML customization
- * file.
- */
- public String getReference () {
-// -----------------------------
- return sid;
- }
-
- public Scenario[] getScenarii () {
-// --------------------------------
- return scenarii.toArray(new Scenario[scenarii.size()]);
- }
-
-/**
- * Returns the validation cycle of the given document type.
- *
- * @param doc the document type being subject of validation
- * @return the validation cycle of the document, or null if not defined.
- */
- public ValidationCycle getValidationCycleOf (DocumentType type) {
-// ---------------------------------------------------------------
- if (validactor == null) setShortCuts();
- ValidationCycle result = validactor.get(type.getName());
- if (result == null) {
- if (type.isStepResult()) result = validactor.get("default"); // "default" validation cycle defined in the configuration, if exist
- if (result == null) result = validactor.get("built-in");
- }
- return result;
- }
-
- public String getVersion () {
-// ---------------------------
- return version;
- }
-
- public Visibility getVisibility () {
-// ----------------------------------
- return visibility;
- }
-
-/**
- * Checks if the given user is actor of this study.
- * Actors include contributors, reviewers and approvers.
- *
- * @return true if the given user is actor of this study.
- * @see #getActors()
- */
- public boolean hasActor (User user) {
-// -----------------------------------
- if (user == null) return false;
- for (Iterator<User> i=this.getActors().iterator(); i.hasNext(); ) {
- User involved = i.next();
- if (involved.equals(user)) return true;
- }
- return false;
- }
-
-/**
- * Checks whether this study is in the Public or the Reference area of the repository.
- *
- * @return true if the study is public.
- * @see #moveToPublic()
- * @see #moveToReference()
- */
- public boolean isPublic () {
-// --------------------------
- return (visibility != Visibility.PRIVATE);
- }
-/**
- * Checks if the given user participates to this study.
- * The Study staff includes the author and contributors.
- *
- * @return true if the given user is actor of this study.
- * @see #getContributors()
- */
- public boolean isStaffedBy (User user) {
-// --------------------------------------
- if (user == null) return false;
- if (manager.equals(user)) return true;
- for (Iterator<User> i=getContributors().iterator(); i.hasNext();) {
- if (i.next().equals(user)) return true;
- }
- return false;
- }
-
- public boolean isVersioned () {
-// -----------------------------
- return (history > 0);
- }
-
-/**
- * Moves this study from the Private to the Public area of the repository.
- *
- * @return true if the move succeeded.
- * @see #isPublic()
- */
- public boolean moveToPublic () {
-// ------------------------------
- if (visibility != Visibility.PRIVATE) return false;
-
- this.visibility = Visibility.PUBLIC;
- if ( updateMe() ) {
- return updateKnowledgeElementsIndex(); // If fails, the database roll-back is under responsibility of the caller
- }
- return false;
- }
-
-/**
- * Moves this study from the Public to the Reference area of the repository.
- * For being moved to the Reference area, the study must previously be approved.
- *
- * @return true if the move succeeded.
- * @see #moveToPublic()
- * @see #isPublic()
- * @see Publication#approve(Date)
- */
- public boolean moveToReference () {
-// ---------------------------------
- if (state != ProgressState.APPROVED) return false;
- if (visibility != Visibility.PUBLIC) return false;
-
- this.visibility = Visibility.REFERENCE;
- if ( updateMe() ) {
- return updateKnowledgeElementsIndex(); // If fails, the database roll-back is under responsibility of the caller
- }
- return false;
- }
-
- public boolean publishes (Document doc) {
-// ---------------------------------------
- if (!super.publishes(doc)) {
- Scenario[] scene = this.getScenarii();
- for (int i=0; i<scene.length; i++) {
- if (scene[i].publishes(doc)) return true;
- }
- }
- return false;
- }
-
- public boolean removeContributor (User... users) {
-// ------------------------------------------------
- if (contributor == null) this.setShortCuts(); // Initializes contributor
- Boolean done = false;
- for (int i=0; i<users.length; i++) {
- User user = users[i];
- for (Iterator<User> j=contributor.iterator(); j.hasNext(); ) {
- User present = j.next();
- if (!present.equals(user)) continue;
-
- this.removeRelation(ContributorRelation.class, user);
- j.remove(); // Updates the contributor shortcut
- done = true;
- break;
- }
- }
- if (done) updateMe();
- return done;
- }
-
- public boolean removeProjectContext (SimulationContext context) {
-// ---------------------------------------------------------------
- boolean done = this.getFirstStep().removeSimulationContext(context);
- updateMe();
- return done;
- }
-
- public void setValidationCycle (DocumentType type, ValidationCycle.Properties vprop) {
-// ------------------------------------------------------------------------------------
- if (validactor == null) setShortCuts(); // Initializes validactor and actor
-
- String cname = type.getName();
- ValidationCycle cycle = validactor.get(cname);
-
- if (cycle != null && cycle.isAssigned()) {
- cycle.resetActors(vprop);
- } else
- try {
- cycle = new ValidationCycle(this, vprop.setDocumentType(type));
-
- ValidationCycleRelation link = cycle.getContext();
- this.addRelation(link);
- validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default,
- }
- catch (Exception error) {
- logger.error("Unable to re-index Knowledge Elements, reason:", error);
- return;
- }
- resetActorsShortCut();
- updateMe(); // Re-index the study, just in case
- }
-
- public boolean shares (Document doc) {
-// ------------------------------------
- Scenario[] scene = this.getScenarii(); // If shared from within the study, the document is shared by the scenarios
- int counter = 0;
-
- for (int i=0; i<scene.length; i++) {
- if (!scene[i].publishes(doc)) continue;
- if (counter == 1) return true;
- counter += 1;
- }
- return false;
- }
-
- public boolean update (Properties sprop) throws InvalidPropertyException {
-// ----------------------------------------
- if (sprop.title != null) this.title = sprop.title;
- if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
-//TODO: To be completed
- return updateMe();
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected boolean buildReference () {
-// -----------------------------------
- String pattern = getReference(); // The study being supposed just created, its reference is the reference pattern
- IDBuilder tool = Database.selectIDBuilder(credate);
- if (tool == null) {
- tool = new IDBuilder(credate);
- Database.getSession().save(tool);
- }
- this.sid = tool.buildReference(pattern, this);
- return true;
- }
-
-/**
- * Demotes this study from In-Check to In-Draft then In-Work states.
- * This function is called internally when demoting the final result document of the study.
- *
- * @return true if the demotion succeeded.
- */
- protected boolean demote () {
-// ---------------------------
- if (state == ProgressState.inCHECK) state = ProgressState.inDRAFT;
- else if (state == ProgressState.inDRAFT) state = ProgressState.inWORK;
- else return false;
- return updateMe();
- }
-
- protected int generateLocalIndex () {
-// -----------------------------------
- docount = docount + 1;
- Database.getSession().update(this);
- return docount;
- }
-
- protected int getLastLocalIndex () {
-// ----------------------------------
- return docount;
- }
-
- protected void loadWorkflow () {
-// ------------------------------
- setShortCuts();
- }
-/**
- * Promotes this study from In-Work to In-Draft then In-Check and APPROVED states.
- * This function is called internally when promoting the final result document of the study.
- *
- * @return true if the demotion succeeded.
- */
- protected boolean promote () {
-// ----------------------------
- if (state == ProgressState.inWORK) {
- state = ProgressState.inDRAFT;
- } else
- if (state == ProgressState.inDRAFT) {
- this.state = ProgressState.inCHECK;
- Revision myvers = new Revision(version);
- if (myvers.isMinor()) {
- version = myvers.incrementAs(state).toString();
- }
- } else
- if (state == ProgressState.inCHECK) {
- state = ProgressState.APPROVED;
- }
- else return false;
-
- return updateMe();
- }
-
-// ==============================================================================================================================
-// Private member functions
-// ==============================================================================================================================
-
- private void resetActorsShortCut () {
-// -----------------------------------
- actor.clear();
-// Get all actors involved in validation cycles
- for (Iterator<ValidationCycle> i=validactor.values().iterator(); i.hasNext(); ) {
- ValidationCycle cycle = i.next();
- User[] user = cycle.getAllActors();
- for (int j=0; j<user.length; j++) actor.add(user[j]);
- }
-// Get all other actors
- for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
- Relation link = i.next();
- Class<?> kindof = link.getClass().getSuperclass();
- if (!kindof.equals(ActorRelation.class)) continue;
- actor.add( ((ActorRelation)link).getTo() );
- }
- }
-
- private void setShortCuts () {
-// ----------------------------
- contributor = new Vector<User>();
- validactor = new HashMap<String,ValidationCycle>();
- actor = new HashSet<User>();
-
-// Get the contributors
- for (Iterator<Relation> i=getRelations(ContributorRelation.class).iterator(); i.hasNext(); ) {
- ContributorRelation link = (ContributorRelation)i.next();
- contributor.add(link.getTo());
- }
-// Get the validation cycles specific to this study
- for (Iterator<Relation> i=getRelations(ValidationCycleRelation.class).iterator(); i.hasNext(); ) {
- ValidationCycleRelation link = (ValidationCycleRelation)i.next();
- validactor.put(link.getDocumentType().getName(), link.getTo()); // The associated document type is necessarily not null in this context
- }
-// Get the validation cycles coming from the configured workflow and not overridden in this study
- for (Iterator<ProjectSettings.ValidationCycle> i=ProjectSettings.getAllValidationCycles().iterator(); i.hasNext(); ) {
- ProjectSettings.ValidationCycle cycle = i.next();
- String type = cycle.getName();
- if (!validactor.containsKey(type)) validactor.put(type, new ValidationCycle(this, cycle));
- }
-// Get all corresponding actors
- for (Iterator<ValidationCycle> i=validactor.values().iterator(); i.hasNext(); ) {
- ValidationCycle cycle = i.next();
- User[] user = cycle.getAllActors();
- for (int j=0; j<user.length; j++) actor.add(user[j]);
- }
-// Get all other actors
- for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
- Relation link = i.next();
- Class<?> kindof = link.getClass().getSuperclass();
- if (!kindof.equals(ActorRelation.class)) continue;
- actor.add( ((ActorRelation)link).getTo() );
- }
- }
-
- private boolean updateKnowledgeElementsIndex() {
-// ----------------------------------------------
- try {
- Index lucin = Database.getIndex();
-
- for (Iterator<Scenario> i=scenarii.iterator(); i.hasNext(); ) {
- Scenario scene = i.next();
- for (Iterator<KnowledgeElement> j=scene.getAllKnowledgeElements().iterator(); j.hasNext(); ) {
- KnowledgeElement kelm = j.next();
- lucin.update(kelm);
- }
- }
- return true;
- }
- catch (Exception error) {
- logger.error("Unable to re-index Knowledge Elements, reason:", error);
- return false;
- }
- }
-
- private boolean updateMe () {
-// ---------------------------
- try {
- Database.getSession().update(this); // Update of relational base
- Database.getIndex().update(this); // Update of Lucene index
- return true;
- }
- catch (Exception error) {
- logger.error("Unable to re-index the study '" + getIndex() + "', reason:", error);
- return false;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class defining the default rights related to operations on studies.
- * On the contrary of documents, a study cannot directly be reviewed or approved. It is reviewed or approved through
- * its final report.
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.User;
-
-
-public class StudyRights {
-
- private User user;
- private Study operand;
- private boolean author = false; // For optimizing
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
- public StudyRights (User user, Study study) {
-// -------------------------------------------
- this.user = user;
- this.operand = study;
- this.author = operand.getAuthor().equals(user); // user may be null
- }
- public StudyRights (Study study) {
-// --------------------------------
- this.user = study.getAuthor();
- this.operand = study;
- this.author = true; // In order to ignore the author in this context
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public boolean canAddScenario () {
-// --------------------------------
- if (operand.getProgressState() != ProgressState.inWORK && operand.getProgressState() != ProgressState.inDRAFT) return false;
- return operand.isStaffedBy(user);
- }
-
-/**
- * Checks if the user has right to edit the description of the study.
- * All actors of the study have such right, including the author, contributors, reviewers and approvers.
- *
- * @return true if the user has right to edit the description.
- */
- public boolean canEditDescription () {
-// ------------------------------------
- return (operand.getAuthor().equals(user) || operand.hasActor(user));
- }
-
- public boolean canEditProperties () {
-// -----------------------------------
- return author;
- }
-
-/**
- * Checks if the user has right to move the study from the Private to the Public area of the repository.
- * Only the author of the study have such right.
- *
- * @return true if the user has right to edit the description.
- */
- public boolean canPublish () {
-// ----------------------------
- if (!author) return false;
- return (!operand.isPublic());
- }
-
- public boolean canPurge () {
-// --------------------------
- if (!author) return false;
- return operand.isVersioned();
- }
-
- public boolean canRemove () {
-// ---------------------------
- if (operand.getProgressState() != ProgressState.inWORK && operand.getProgressState() != ProgressState.inDRAFT) return false;
- return author;
- }
-
- public boolean canVersion () {
-// ----------------------------
- if (operand.getProgressState() != ProgressState.inWORK && operand.getProgressState() != ProgressState.inDRAFT) return false;
- return operand.isStaffedBy(user);
- }
-
-// ==============================================================================================================================
-// Getter
-// ==============================================================================================================================
-
- public Study getOperand () {
-// --------------------------
- return operand;
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <typedef name="StampType" class="org.splat.kernel.GenericEnumType">
- <param name="enumClassName">org.splat.som.ValidationStep</param>
- </typedef>
-
- <class name="org.splat.som.Timestamp" table="stamp" lazy="false">
-
-<!-- Properties inherited from Any
- -->
- <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
- <generator class="org.splat.kernel.IDGenerator"/>
- </id>
- <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
- <key column="owner" />
- <one-to-many class="org.splat.kernel.Attribute" />
- </set>
-
-<!-- Timestamp properties
- -->
- <!-- StampRelation context -->
- <one-to-one name="context" property-ref="refer" access="field" />
-
- <!-- ValidationCycle.Step mytype -->
- <property type="StampType" name="mytype" column="type" access="field" not-null="true" />
-
- <!-- User author -->
- <many-to-one name="author" column="author" access="field" not-null="true" />
-
- <!-- Date sdate, including the time section -->
- <property type="timestamp" name="sdate" column="date" access="field" not-null="true" />
-
- </class>
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.Comparator;
-import java.util.Date;
-
-import org.splat.kernel.Any;
-import org.splat.kernel.Attribute;
-import org.splat.kernel.User;
-
-
-public class Timestamp extends Any {
-
- private StampRelation context;
- private ValidationStep mytype;
- private User author;
- private Date sdate;
-
- public static class ComparatorByDate implements Comparator<Timestamp> {
-// ---------------------------------------------------------------------
- public int compare(Timestamp t1, Timestamp t2)
- {
- return t1.getDate().compareTo(t2.getDate());
- }
- }
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected Timestamp () {
- }
-// Internal constructors
- protected Timestamp (ValidationStep type, Document from, User to, Date sdate) {
-// -----------------------------------------------------------------------------
- super((Attribute)null); // For building the collection of attributes
- this.mytype = type;
- this.author = to;
- this.sdate = sdate;
- this.context = new StampRelation(from, this);
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public User getAuthor () {
-// ------------------------
- return author;
- }
-
- public String getComment () {
-// ---------------------------
- CommentAttribute field = (CommentAttribute)this.getAttribute(CommentAttribute.class);
- String result = null;
- if (field != null) result = field.getValue();
- return result;
- }
-
- public Date getDate () {
-// ----------------------
- return sdate;
- }
-
- public ValidationStep getType () {
-// --------------------------------
- return mytype;
- }
-
- public void setComment (String comment) {
-// ---------------------------------------
- if (comment != null) this.setAttribute( new CommentAttribute(this, comment) );
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected StampRelation getContext () {
-// -------------------------------------
- return context;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-
-
-public class UsedByRelation extends Relation {
-
- private Document refer;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected UsedByRelation () {
- }
-// Initialization constructors
- protected UsedByRelation (Document from, Document to) {
-// -----------------------------------------------------
- super(from);
- this.refer = to;
- this.reverse = new UsesRelation(this, to, from);
- }
-// Internal constructor
- protected UsedByRelation (Relation back, Document from, Document to) {
-// --------------------------------------------------------------------
- super(from);
- this.refer = to;
- this.reverse = back;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Class<? extends Relation> getReverseClass () {
-// ---------------------------------------------------
- return UsesRelation.class;
- }
- public Document getTo () {
-// -------------------------
- return refer;
- }
- public boolean isBidirectional () {
-// ---------------------------------
- return true;
- }
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (Document)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-
-
-public class UsesRelation extends Relation {
-
- private Document refer;
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected UsesRelation () {
- }
-// Initialization constructors
- protected UsesRelation (Document from, Document to) {
-// ---------------------------------------------------
- super(from);
- this.refer = to;
- this.reverse = new UsedByRelation(this, to, from);
- }
-// Internal constructor
- protected UsesRelation (Relation back, Document from, Document to) {
-// ------------------------------------------------------------------
- super(from);
- this.refer = to;
- this.reverse = back;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public Class<? extends Relation> getReverseClass () {
-// ---------------------------------------------------
- return UsedByRelation.class;
- }
-
- public Document getTo () {
-// -------------------------
- return refer;
- }
- public boolean isBidirectional () {
-// ---------------------------------
- return true;
- }
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (Document)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
-<!--
- -
- - @author Daniel Brunier-Coulin
- - @copyright OPEN CASCADE 2012
- -->
-
-<hibernate-mapping>
-
- <class name="org.splat.som.ValidationCycle" table="cycle" lazy="false">
-
-<!-- Properties inherited Persistent
- -->
- <id name="rid" column="rid" access="field">
- <generator class="increment"/>
- </id>
-
-<!-- ValidationCycle properties
- -->
- <!-- ValidationCycleRelation context -->
- <one-to-one name="context" property-ref="refer" access="field" />
-
- <!-- DocumentType mytype -->
- <many-to-one name="mytype" column="type" access="field" not-null="true" />
-
- <!-- User publisher -->
- <many-to-one name="publisher" column="publisher" access="field" />
-
- <!-- User reviewer -->
- <many-to-one name="reviewer" column="reviewer" access="field" />
-
- <!-- User approver -->
- <many-to-one name="approver" column="approver" access="field" />
-
- <!-- User signatory -->
- <many-to-one name="signatory" column="signatory" access="field" />
-
- </class>
-</hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- * Class defining the validation cycle applicable to documents of a given type.<br/>
- * A validation cycle specifies the validation steps of documents complying with by this cycle, as well as the actors
- * involved in such validations. Once past, each validation step is written down by a time-stamp attached to the validated
- * document.<br/>
- * <br/>
- * The possible validation steps are Promotion, Review, Approval and Acceptance (or Refusal), all being optional,
- * except Promotion.<br/>
- * When enabled, Review and Approval involve one given user while Promotion and Acceptance have default actors defined by
- * the application. The default actors are:
- * <ul>
- * <li>Promotion by either the author of the document or the responsible of study</li>
- * <li>Acceptance by the customer, possibly represented by an internal user</li>
- * </ul>
- * Explicit Promotion and Acceptance actors can be defined, for example to force some documents to be published by the
- * responsible of study only.<br/>
- * <br/>
- * Default validation cycles are defined in the configuration workflow, the responsible of studies overriding them when necessary.
- * They are attached to studies at a given document type.<br/>
- *
- * @see Study#addValidationCycle(DocumentType,Properties)
- * @see Study#getValidationCycleOf(DocumentType)
- * @see Timestamp
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import java.util.List;
-import java.util.Vector;
-
-import org.splat.kernel.InvalidPropertyException;
-import org.splat.kernel.MissedPropertyException;
-import org.splat.kernel.MultiplyDefinedException;
-import org.splat.kernel.Persistent;
-import org.splat.kernel.User;
-import org.splat.kernel.UserDirectory;
-
-public class ValidationCycle extends Persistent {
-
- private ValidationCycleRelation context;
- private DocumentType mytype; // Null if the referenced validation cycle is a default one
- private User publisher;
- private User reviewer; // Null if no REVIEW validation step
- private User approver; // Null if no APPROVAL validation step
- private User signatory; // Null if no ACCEPTANCE validation step
-
- public enum Actor {
- manager, // Responsible of study
- Nx1, // N+1 manager of the responsible of study
- Nx2, // N+2 manager of the responsible of study
- customer // Customer
- }
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Fields initialization class
- public static class Properties extends Persistent.Properties {
-// ------------------------------------------------------------
- DocumentType doctype = null;
- User publisher = null;
- User reviewer = null;
- User approver = null;
- User signatory = null;
-
-// - Public services
-
- public void clear () {
- super.clear();
- doctype = null;
- publisher = null;
- reviewer = null;
- approver = null;
- signatory = null;
- }
-// - Protected services
-
- protected Properties setDocumentType (DocumentType type)
- {
- doctype = type;
- return this;
- }
-// - Properties setter
-
- public Properties setActor (ValidationStep step, User actor)
- {
- if (step == ValidationStep.PROMOTION) publisher = actor;
- else if (step == ValidationStep.REVIEW) reviewer = actor;
- else if (step == ValidationStep.APPROVAL) approver = actor;
- else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) signatory = actor;
- return this;
- }
-// - Global validity check
-
- public void checkValidity() throws MissedPropertyException
- {
- if (doctype == null) throw new MissedPropertyException("type");
- }
- }
-// Database fetch constructor
- protected ValidationCycle () {
- }
-// Internal constructors
- protected ValidationCycle (Study from, ProjectSettings.ValidationCycle cycle) {
-// -----------------------------------------------------------------------------
- Actor[] actype = cycle.getActorTypes();
- User.Properties uprop = new User.Properties();
-
- mytype = Document.selectType(cycle.getName()); // Null in case of default validation cycle
-// context = new ValidationCycleRelation(from, this);
- context = null; // Validation cycle defined in the workflow
- for (int i=0; i<actype.length; i++) {
- User actor = null;
- if (actype[i] != null)
- try {
- if (actype[i] == Actor.manager) {
- actor = from.getAuthor();
- } else
- if (actype[i] == Actor.Nx1) {
- List<User> manager = UserDirectory.selectUsersWhere(uprop.setOrganizationName("Nx1"));
- if (manager.size() == 1) actor = manager.get(0);
- } else
- if (actype[i] == Actor.Nx2) {
- List<User> manager = UserDirectory.selectUsersWhere(uprop.setOrganizationName("Nx2"));
- if (manager.size() == 1) actor = manager.get(0);
- } else { /* Actor.customer */
- actor = from.getAuthor();
-//TODO: Get the customer of the study, if exists
- }
- } catch (Exception e) { // Should not happen
- actor = null;
- }
- if (i == 0) reviewer = actor;
- else if (i == 1) approver = actor;
- else if (i == 2) signatory = actor;
- }
- }
- protected ValidationCycle (Study from, Properties vprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
-// --------------------------------------------------------
- super(vprop); // Throws one of the above exception if not valid
- mytype = vprop.doctype;
- publisher = vprop.publisher; // May be null
- reviewer = vprop.reviewer; // May be null
- approver = vprop.approver; // May be null
- signatory = vprop.signatory; // May be null
- context = new ValidationCycleRelation(from, this);
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-/**
- * Checks if a given validation step is enabled in this validation cycle.
- *
- * @param step the validation step checked.
- * @return true if the given validation step is enabled.
- */
- public boolean enables (ValidationStep step) {
-// -------------------------------------------
- if (step == ValidationStep.PROMOTION) return true;
- else if (step == ValidationStep.REVIEW) return (reviewer != null);
- else if (step == ValidationStep.APPROVAL) return (approver != null);
- else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) return (signatory != null);
- return false;
- }
-
-/**
- * Returns the user involved in a given step of this document validation cycle.
- * When enabled, the Review and Approval steps have one explicit actor returned by this function. On the other hand,
- * Promotion and Acceptance have default actors - they respectively are the author of the document or the responsible of study,
- * and the customer or its representative internal user. In this context, a null user is returned.
- *
- * @param step the validation step
- * @return the user involved by the given step or null if the step is disabled or the actors are the default ones
- * @see #getAllActors()
- * @see #enables
- */
- public User getActor (ValidationStep step) {
-// -----------------------------------------
- if (step == ValidationStep.PROMOTION) return publisher;
- else if (step == ValidationStep.REVIEW) return reviewer;
- else if (step == ValidationStep.APPROVAL) return approver;
- else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) return signatory;
- return null;
- }
-
-/**
- * Returns all explicit actors of this document validation cycle, that is, actors of enabled validation cycles, excluding
- * the default actors.
- *
- * @return the users explicitly involved by the steps of this validation cycle
- * @see #getActor(ValidationStep)
- * @see #enables(ValidationStep)
- */
- public User[] getAllActors () {
-// -----------------------------
- Vector<User> result = new Vector<User>();
- if (publisher != null) result.add(publisher);
- if (reviewer != null) result.add(reviewer);
- if (approver != null) result.add(approver);
- if (signatory != null) result.add(signatory);
- return result.toArray(new User[result.size()]);
- }
-
-/**
- * Return the document type to which this validation cycle applies. If this validation cycle is a default one, the document
- * type is not defined.
- *
- * @return the document type involved by this validation cycle, or null if this validation cycle is a default one.
- * @see #isDefault()
- */
- public DocumentType getDocumentType () {
-// --------------------------------------
- return mytype; // May be null
- }
-
-/**
- * Checks if this validation cycle is assigned to a study. If not, it is common to all studies of the workflow in which it has
- * been defined.
- *
- * @return true if this validation cycle is assigned to a study.
- */
- public boolean isAssigned () {
-// ----------------------------
- return (context != null);
- }
-
-/**
- * Checks if this validation cycle is a default one, either specific to a Study or defined in the configuration workflow or
- * built-in.<br/>
- * Default validation cycle are not attached to any document type. As for built-in ones, they doesn't include any validation step
- * other than Promotion.
- *
- * @return true if this validation cycle is a default one.
- * @see #getDocumentType()
- * @see ProjectSettings#getNewValidationCycle()
- */
- public boolean isDefault () {
-// ---------------------------
- return (mytype == null);
- }
-
-// ==============================================================================================================================
-// Protected services
-// ==============================================================================================================================
-
- protected ValidationCycleRelation getContext () {
-// -----------------------------------------------
- return context;
- }
-
- protected void remove (ValidationStep step) {
-// ------------------------------------------
- if (step == ValidationStep.REVIEW) reviewer = null;
- else if (step == ValidationStep.APPROVAL) approver = null;
- else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) signatory = null;
- if (this.isSaved()) Database.getSession().update(this);
- }
-
- protected void resetActors (Properties vprop) {
-// ---------------------------------------------
- publisher = vprop.publisher; // May be null
- reviewer = vprop.reviewer; // May be null
- approver = vprop.approver; // May be null
- signatory = vprop.signatory; // May be null
- if (this.isSaved()) Database.getSession().update(this);
- }
-
- protected void setActor (ValidationStep step, User actor) {
-// --------------------------------------------------------
- if (step == ValidationStep.PROMOTION) publisher = actor;
- else if (step == ValidationStep.REVIEW) reviewer = actor;
- else if (step == ValidationStep.APPROVAL) approver = actor;
- else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) signatory = actor;
- if (this.isSaved()) Database.getSession().update(this);
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-
-
-public class ValidationCycleRelation extends Relation {
-
- private ValidationCycle refer;
-
-// ==============================================================================================================================
-// Construction
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected ValidationCycleRelation () {
- }
-// Internal constructor
- protected ValidationCycleRelation (Study from, ValidationCycle to) {
-// ------------------------------------------------------------------
- super(from);
- this.refer = to;
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
-/**
- * Returns the document type to which the validation cycle referenced by this relation applies. If the referenced validation cycle
- * is a default one, the associated document type is not defined.
- *
- * @return the document type involved by the referenced validation cycle, or null if this latter is a default one.
- */
- public DocumentType getDocumentType () {
-// --------------------------------------
- return refer.getDocumentType();
- }
-
- public ValidationCycle getTo () {
-// -------------------------------
- return refer;
- }
-
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (ValidationCycle)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public enum ValidationStep {
- PROMOTION, REVIEW, APPROVAL, ACCEPTANCE, // Validation steps subject of time stamp
- DISTRIBUTION, REFUSAL // Additional Time stamps
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-import org.splat.kernel.Persistent;
-import org.splat.kernel.Relation;
-
-
-public class VersionsRelation extends Relation {
-
-// Persistent field
- private Document refer;
-
-// Transient fields
- private boolean got; // For optimizing getDescription()
- private String description; // Null if this is not described
-
-// ==============================================================================================================================
-// Constructors
-// ==============================================================================================================================
-
-// Database fetch constructor
- protected VersionsRelation () {
-// -----------------------------
- got = false;
- description = null;
- }
-// Initialization constructors
- protected VersionsRelation (Document from, Document to) {
-// -------------------------------------------------------
- super(from);
- this.refer = to;
- this.got = true;
- this.description = null; // Conversion not described
- }
- protected VersionsRelation (Document from, Document to, String description) {
-// ---------------------------------------------------------------------------
- super(from);
- this.refer = to;
- this.got = true;
- this.description = description; // May be null
- if (description != null) this.setAttribute( new DescriptionAttribute(this, description) );
- }
-
-// ==============================================================================================================================
-// Public member functions
-// ==============================================================================================================================
-
- public String getDescription () {
-// -------------------------------
- if (!got) {
- DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
- if (field != null) description = field.getValue();
- got = true; // Don't need to be modified later as set and remove attribute functions are private to this class
- }
- return description; // May be null
- }
-
- public Document getTo () {
-// -------------------------
- return refer;
- }
- protected void setTo (Persistent to) {
-// ------------------------------------
- refer = (Document)to;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.splat.som;
-/**
- *
- * @author Daniel Brunier-Coulin
- * @copyright OPEN CASCADE 2012
- */
-
-public enum Visibility {
- PRIVATE, // Qualifies studies stored into the private area
- PUBLIC, // Qualifies studies stored into the public area
- REFERENCE // Qualifies studies stored into the reference area
-}
\ No newline at end of file
+++ /dev/null
-name.module = Centre d''études
-
-size.format = #,##0 Ko
-date.format = dd/MM/yyyy
-dd/MM/yyyy = jj/mm/aaaa
-
-menu.step.1 = Spécifier l''étude
-menu.step.2 = Concevoir le scénario
-menu.step.3 = Créer la géométrie
-menu.step.4 = Générer le modèle d''analyse
-menu.step.5 = Entrer les conditions de calcul
-menu.step.6 = Effectuer le calcul
-menu.step.7 = Analyser les résultats
-menu.step.8 = Capitaliser ce cas d''étude
-menu.step.9 = Finaliser l''étude
-
-folder.step.1 = Spécification de l''étude
-folder.step.2 = Description du scénario
-folder.step.3 = Géométrie
-folder.step.4 = Modèle d''analyse
-folder.step.5 = Conditions de calcul
-folder.step.6 = Schéma de calcul
-folder.step.7 = Résultats
-folder.step.8 = Élements de connaissances
-folder.step.9 = Rapport final
-
-type.document.requirements = Cahier des charges
-type.document.specification = Document de spécification
-type.document.design = Document de conception
-type.document.geometry = Géométrie
-type.document.model = Modèle d''analyse
-type.document.loads = Conditions de calcul
-type.document.script = Script d''exécution
-type.document.log = Log d''exécution
-type.document.results = Résultats de calcul
-type.document.report = Rapport final
-type.document.memorandum = Note technique
-type.document.minutes = Compte rendu
-
-type.context.customer = Client
-type.context.product = Produit
-type.context.phase = Phase du produit
-type.context.need = Besoin client
-type.context.purpose = Finalité de l''étude
-type.context.physic = Type de physique
-type.context.object = Objet étudié
-type.context.part = Objet modélisé
-type.context.geometry = Type de géométrie
-type.context.model = Type de modèle
-type.context.element = Type d''éléments
-type.context.shape = Géométrie des éléments
-type.context.order = Degré des éléments
-type.context.analysis = Type d''analyse
-type.context.platform = Plate-forme logicielle
-type.context.module = Module de calcul
-type.context.component = Brique technologique
-
-type.knowledge.bestpractice = Bonne pratique
-type.knowledge.limitation = Limitation
-type.knowledge.inconsistency = Incohérence
-type.knowledge.metrics = Métrique
-type.knowledge.improvement = Amélioration
-
-history.creation = Document créé par
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<project-structure>
-
-
-<!-- 1. Database physical location
- The database includes an SQL base containing the studies and the document metadata, a Lucene index used for searching studies and
- knowledges, a file vault including all actual data and a directory where files uploaded and downloaded by users are temporarily saved.
- All these information are located in sub-directories of a common root directory defined below.
- This directory must be visible from the server application (Tomcat).
- -->
- <database>
- <repository disk="C:/Repository" />
- </database>
-
-
-<!-- 2. Formats
- -->
- <formats>
-
-<!-- 2.1 Project elements identification scheme
- Studies, Knowledges and Documents are identified by unique user references. The structure of these references is customizable.
- You customize references through patterns.
- A reference's pattern is a character string including format directives. These format directives allow you to insert
- some information into the reference. The following directives are available:
- - %yy or %yyyy for inserting the entity creation year on 2 or 4 digits
- - %0000 for inserting a unique index, the number of digits being defined by the number of 0
- The above index is unique in the scope of cycle defined by the first format directive (year). In other words, this index
- restarts every new year. As such, for making references unique on this application server, both format directives (cycle
- and index) must be present in the pattern.
- Other characters are simply inserted as is in generated references. They can be used for extending the reference uniqueness
- beyond application servers, by adding a prefix specific to a given server (for example, a company department name).
- Given that these references may be used as directory or file names of the repository vault, the pattern must not include
- illicit characters such as '/', '?', '<', '>' etc.
- -->
- <references study="DER%yy%0000"/>
-
-<!-- 2.2 Physical files naming scheme
- The physical data files stored into the repository vault can be named as follows:
- - By the user-defined title of corresponding documents ("title" name attribute below)
- - Encoded by a built-in scheme ("encoded" name attribute)
- - As is, that is, by keeping the name of the imported file ("asis" name attribute - not yet supported)
- Remarks:
- - When using the title scheme, as file names may include accent characters, client browsers must be configured for
- NOT encoding URLs as UTF-8.
- - Whatever is the naming scheme used, in order to avoid name clashes, file names are anyway suffixed by an index
- unique in the scope of the owner study.
- -->
- <files name="encoded"/>
-
-<!-- 2.3 Document versions format
- Defines the format in which version numbers are presented to users.
- A version number includes a major, a minor and a branch number, when exist.
- -->
- <versions pattern="%M.%m[-%s]"/>
- </formats>
-
-
-<!-- 3. Study step types
- The user activities involved in studies are defined by study step types. The tag below simply lists all possible steps
- applicable in a workflow.
- Step types are defined by type names used in the API for accessing to study activities.
- The document data produced during these activities are saved into the repository vault. They can be structured in
- sub-directories of each study root directory. As such, the definition of study step types includes the path of the
- corresponding sub-directory.
- The list below does not define the order of steps - this order is specified by the workflow. The steps are listed in
- an order defining the internal index of steps. These index are used for localizing the activity names and corresponding
- folder names.
-
- Remark:
- - "scenario" is a reserved type name.
- -->
- <steps>
- <article type="specification" path="1.Study"/>
- <article type="design" path="1.Study"/>
- <article type="modeling" path="2.Geometry"/>
- <article type="meshing" path="3.Mesh"/>
- <article type="preprocessing" path="4.Load"/>
- <article type="solving" path="5.Result"/>
- <article type="postprocessing" path="6.Analysis"/>
- <article type="capitalization" path="7.Knowledge"/>
- <article type="reporting" path="1.Study"/>
- </steps>
-
-
-<!-- 4. Document types
- All documents under the control of the Study Manager are typed. The tag below simply lists all possible document types
- involved in a workflow.
- Document types are defined by type names used in the API for manipulating document types. These type names are also used
- for localizing document types.
- The documents have dependencies in accordance to their type. As such, the definition of each document type include the
- potential dependencies of corresponding documents.
-
- Warning: Articles must be ordered in a way that dependent document types (uses attribute values) must previously be defined.
- Example: "requirements" type must be defined before "specification" because "specification" uses "requirements".
- Remarks:
- - The dependencies are transitive (if document A depends on document B, itself depending on C, A implicitly depends on C).
- - "knowledge" is a reserved word qualifying Knowledge Elements. So, it must not be used as a document type name.
- - "default" and "built-in" are also reserved words used for defining validation cycles.
- - In this version, the "uses" attribute is limited to 1 document type only.
- -->
- <documents>
- <article type="requirements"/>
- <article type="specification" uses="requirements"/>
- <article type="design" uses="specification"/>
- <article type="geometry" uses="design"/>
- <article type="model" uses="geometry"/>
- <article type="loads" uses="model"/>
- <article type="script" uses="loads"/>
- <article type="log" uses="script"/>
- <article type="results" uses="script"/>
- <article type="report" uses="results"/>
- <article type="memorandum"/>
- <article type="minutes"/>
- </documents>
-
-
-<!-- 5. Simulation Context types
- As documents, the simulation contexts are typed. The tag below simply lists the simulation context types available initially,
- after the installation of the product. These types can then be extended on the fly by end-users when assigning simulation
- contexts to studies.
- Simulation context types are defined by type names used in the API for manipulating simulation contexts. These type names
- are also used for localizing simulation contexts types.
-
- Warning: The Simulation Context type "product" is mandatory as it is used when creating a study.
- -->
- <contexts>
-
- <!-- General information -->
- <article type="customer"/>
- <article type="product"/>
- <article type="phase"/> <!-- Phase of the product -->
- <article type="need"/> <!-- Customer needs -->
- <article type="purpose"/> <!-- Objective of the study -->
- <article type="physic"/> <!-- Structure analysis, Thermal-hydraulics, Neutronic... -->
-
- <!-- Geometry characteristics Examples: -->
- <article type="object"/> <!-- Car, Plane, Equipment... -->
- <article type="part"/> <!-- Crankcase, Outer layer... -->
- <artivle type="geometry"/> <!-- Surface, Volume -->
-
- <!-- Model characteristics Examples: -->
- <article type="model"/> <!-- CSG, FEM... -->
- <article type="element"/> <!-- Bar, Surface, Volume -->
- <article type="shape"/> <!-- (Surface) Triangle, Quadrangle... (Volume) Tetrahedron, Hexahedron... -->
- <article type="order"/> <!-- First-order, Second-order... -->
-
- <!-- Analysis type Examples: -->
- <article type="analysis"/> <!-- Static, Dynamic... -->
-
- <!-- Software tools used -->
- <article type="platform"/>
- <article type="module"/>
- <article type="component"/>
- </contexts>
-
-
-<!-- 6. Knowledge Elements types
- As documents and simulation contexts, the knowledges are typed. The tag below lists these knowledge types.
- Knowledge types are simply defined by type names used in the API for manipulating knowledge types. These type names
- are also used for localizing knowledge types.
-
- Warning: The Knowledge Elements type "usecase" is reserved for internal use.
- -->
- <knowledges>
- <article type="bestpractice"/>
- <article type="limitation"/>
- <article type="inconsistency"/>
- <article type="metrics"/>
- <article type="improvement"/>
- </knowledges>
-
-
-<!-- 7. User activities
-
- Remarks:
- - Step names must naturally be unique.
- - Simulation Contexts must be attached to one classification step only.
- - Result document types must be results of one step only and be part of contents of the corresponding step.
- -->
- <activities>
- <step name="specification">
- <classification context="customer,product,phase,need,purpose,physic"/>
- <flow contents="requirements,specification,minutes" result="specification"/>
- <storage path="1.Study"/>
- </step>
- <scenario>
- <step name="design">
- <flow contents="design,memorandum,minutes" result="design"/>
- <storage path="1.Study"/>
- </step>
- <step name="modeling">
- <classification context="object,part,geometry"/>
- <flow contents="geometry,memorandum,minutes" result="geometry"/>
- <storage path="2.Geometry"/>
- </step>
- <step name="meshing">
- <classification context="model,element,shape,order"/>
- <flow contents="model,memorandum,minutes" result="model"/>
- <storage path="3.Mesh"/>
- </step>
- <step name="preprocessing">
- <classification context="analysis"/>
- <flow contents="loads,script,minutes" result="loads"/>
- <storage path="4.Analysis"/>
- </step>
- <step name="solving">
- <classification context="platform,module,component"/>
- <flow contents="log,results,minutes" result="results"/>
- <storage path="5.Result"/>
- </step>
- <step name="postprocessing">
- <flow contents="memorandum,minutes"/>
- <storage path="6.Report"/>
- </step>
- <step name="capitalization">
- <flow contents="knowledge"/>
- <storage path="6.Report"/>
- </step>
- </scenario>
- <step name="reporting">
- <flow contents="report,minutes" result="report"/>
- <storage path="1.Study"/>
- </step>
- </activities>
-
-
-<!-- 8. Document validation cycles
- Validation cycles define the actors involved in the validation steps of documents. These steps can be
- "review", "approval" and "acceptance".
- Remarks:
- - Each validation cycle is defined by a tag corresponding to the type of an activity result document.
- - The actors of validation steps can be
- "manager", referring the responsible of study,
- "Nx1", referring the manager of the department (see User definition for more information),
- "Nx2", referring the boss of the department manager,
- "customer" (most likely involved in the acceptance step).
- -->
- <validations>
- <specification review="Nx1" approval="Nx2"/>
- <report review="Nx1" approval="Nx2"/>
- <default review="manager" />
- </validations>
-
-</project-structure>
\ No newline at end of file
+++ /dev/null
-name.module = Study Manager
-
-size.format = #,##0 Kb
-date.format = MM.dd.yyyy
-MM.dd.yyyy = mm.dd.yyyy
-
-menu.step.1 = Specify the study
-menu.step.2 = Design the scenario
-menu.step.3 = Create the geometry
-menu.step.4 = Generate the analysis model
-menu.step.5 = Enter the boundary conditions
-menu.step.6 = Execute the calculation
-menu.step.7 = Analyze the results
-menu.step.8 = Capitalize this use-case
-menu.step.9 = Finalize the study
-
-folder.step.1 = Specification of the study
-folder.step.2 = Description of the scenario
-folder.step.3 = Geometry
-folder.step.4 = Analysis model
-folder.step.5 = Boundary conditions
-folder.step.6 = Calculation scheme
-folder.step.7 = Calculation results
-folder.step.8 = Knowledge elements
-folder.step.9 = Final report
-
-type.document.requirements = Customer requirements
-type.document.specification = Specification document
-type.document.design = Design document
-type.document.geometry = Geometry
-type.document.model = Analysis model
-type.document.loads = Boundary conditions
-type.document.script = Execution script
-type.document.log = Execution log
-type.document.results = Calculation results
-type.document.report = Final report
-type.document.memorandum = Technical report
-type.document.minutes = Minute meeting
-
-type.context.customer = Customer
-type.context.product = Product
-type.context.phase = Product phase
-type.context.need = Customer needs
-type.context.purpose = Purpose of study
-type.context.physic = Physics
-type.context.object = Studied object
-
-type.context.part = Modeled object
-type.context.geometry = Geometry type
-type.context.model = Type of analysis model
-type.context.element = Element type
-type.context.shape = Geometry of elements
-type.context.order = Order of elements
-type.context.analysis = Analysis type
-type.context.platform = Software platform
-type.context.module = Solver
-type.context.component = Software component
-
-type.knowledge.bestpractice = Best practice
-type.knowledge.limitation = Limitation
-type.knowledge.inconsistency = Inconsistency
-type.knowledge.metrics = Metrics
-type.knowledge.improvement = Improvement
-
-history.creation = Document created by
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<study ref="PLM110001">
-
- <properties title="Évaluation de la dose flash"
- user="ffe"
- date="03/05/2011" />
-
- <contexts>
- <context type="product" value="LMJ"/>
- </contexts>
-
- <step name="specification">
- <document ref="PLM110001.01">
- <properties title="Cahier des charges" type="requirements" format="pdf" author="ffe" date="03/05/2011" state="EXTERN" />
- </document>
- <document ref="PLM110001.02">
- <properties title="Spécifications générales" type="specification" format="xml" author="ffe" date="10/05/2011" state="inDRAFT" />
- <relations>
- <uses ref="PLM110001.01"/>
- </relations>
- </document>
- </step>
- <scenario title="Neutronique">
- <step name="modeling">
- <document ref="PLM110001.03">
- <properties title="Assemblage PCC" type="geometry" format="ProE" author="ffe" date="10/05/2011" state="inDRAFT" />
- <relations>
- <uses ref="PLM110001.02"/>
- </relations>
- </document>
- </step>
- </scenario>
- <scenario title="Activation">
- </scenario>
- <scenario title="Photonique">
- </scenario>
-
-</study>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<users>
-
-<user>
- <first>Jean-Bernard</first>
- <last>Trépon</last>
- <display>Jean-Bernard Trépon</display>
- <username>jbt</username>
- <role>manager</role>
- <mail>jean-bernard.trepon@euriware.fr</mail>
- <organization>Euriware</organization>
-</user>
-
-<user>
- <first>Hervé</first>
- <last>Lexpert</last>
- <display>Hervé</display>
- <username>hl</username>
- <role>manager</role>
- <mail>herve.lexpert@opencascade.com</mail>
- <organization>OC-F</organization>
-</user>
-
-<user>
- <first>Paul</first>
- <last>Durand</last>
- <username>pdd</username>
- <role>studengineer</role>
- <mail>paul.durand@euriware.fr</mail>
- <organization>Euriware</organization>
-</user>
-
-<user>
- <first>Sylvie</first>
- <last>Dupond</last>
- <username>sdd</username>
- <role>manager</role>
- <mail>sylvie.dupond@cea.fr</mail>
- <organization>CEA</organization>
-</user>
-
-<user>
- <first>Michel</first>
- <last>Karyo</last>
- <username>mko</username>
- <password>mko</password>
- <role>manager</role>
- <mail>michel.karyo@opencascade.com</mail>
- <organization>Nx1</organization>
-</user>
-
-<user>
- <first>Pierre</first>
- <last>Jarnet</last>
- <username>pjt</username>
- <password>pjt</password>
- <role>manager</role>
- <mail>pierre.jarnet@euriware.fr</mail>
- <organization>Nx2</organization>
-</user>
-
-</users>
\ No newline at end of file
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry excluding="**/CVS/*" kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/SPlat"/>
- <classpathentry exported="true" kind="lib" path="/SPlat/dist/splat-kernel.jar"/>
<classpathentry exported="true" kind="lib" path="/SPlat/dist/splat-manox.jar"/>
- <classpathentry exported="true" kind="lib" path="/SPlat/dist/splat-som.jar"/>
<classpathentry exported="true" kind="lib" path="lib/org.springframework.aop-3.1.2.RELEASE.jar"/>
<classpathentry exported="true" kind="lib" path="lib/org.springframework.asm-3.1.2.RELEASE.jar"/>
<classpathentry exported="true" kind="lib" path="lib/org.springframework.aspects-3.1.2.RELEASE.jar"/>
<!-- build-dist: Create the JAR distribution -->
<!-- ================================================= -->
<target name="build-dist" depends="clean, splat, build-stub" description="Builds the JAR distribution">
- <echo message="build ${siman-common.jar.name}.jar" />
+ <echo message="build ${siman-common.jar.name}" />
<!-- <antcall target="compile-java">
</antcall>-->
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<workflow name="Cast3M">
+
+<!-- 1. Simulation Contexts
+ Defines the default simulation contexts common to all studies applying this workflow. These simulation contexts
+ will automatically be assigned to studies at creation time.
+ Each simulation context is set through a tag corresponding to the name of a simulation context type previously
+ defined in the SOM structure.
+ -->
+ <contexts>
+ <model value="FEM"/>
+ <platform value="SALOME"/>
+ <module value="Cast3M"/>
+ </contexts>
+
+<!-- 2. User activities
+ Defines the steps involved in this workflow.
+ Each step is defined by a tag corresponding to the name of a step type previously defined in the SOM structure.
+ It includes:
+ - The simulation contexts types relative to the step (tag classification, attribute context)
+ - The document types that can be produced at this step (tag flow, attribute contents)
+ - The document type result of this step (tag flow, attribute result)
+ All simulation contexts and document types must previously be defined in the SOM structure.
+
+ User activities are ordered. They can be attached to scenarios - they are the same for all scenarios of the study -
+ or to the study itself. Attaching an activity to the study makes the data produced during this activity shared by all
+ scenarios of the study (typically, the study requirements).
+
+ Remarks:
+ - Simulation Contexts must be attached to one classification step only.
+ - Result document types must be results of one step only and be part of contents of the corresponding step.
+ - The result document type of the last activity attached to the study makes the result document type of the study itself.
+ -->
+ <activities>
+ <specification>
+ <classification context="customer,product,phase,need,purpose,physic"/>
+ <flow contents="requirements,specification,minutes" result="specification"/>
+ </specification>
+ <scenario>
+ <design>
+ <flow contents="design,memorandum,minutes" result="design"/>
+ </design>
+ <modeling>
+ <classification context="object,part,geometry"/>
+ <flow contents="geometry,memorandum,minutes" result="geometry"/>
+ </modeling>
+ <meshing>
+ <classification context="model,element,shape,order"/>
+ <flow contents="model,memorandum,minutes" result="model"/>
+ </meshing>
+ <preprocessing>
+ <classification context="analysis"/>
+ <flow contents="loads,script,minutes" result="loads"/>
+ </preprocessing>
+ <solving>
+ <classification context="platform,module,component"/>
+ <flow contents="log,results,minutes" result="results"/>
+ </solving>
+ <postprocessing>
+ <flow contents="memorandum,minutes"/>
+ </postprocessing>
+ <capitalization>
+ <flow contents="knowledge"/>
+ </capitalization>
+ </scenario>
+ <reporting>
+ <flow contents="report,minutes" result="report"/>
+ </reporting>
+ </activities>
+
+
+<!-- 3. Document validation cycles
+ The validation cycles define the actors involved in the validation steps of documents. These steps can be
+ "review", "approval" and "acceptance" and applies to document types resulting from an activity.
+ Each validation cycle is defined by a tag corresponding to the type of the result document previously defined
+ in activities.
+
+ Remarks:
+ - The actors of validation steps can be
+ "manager", referring the responsible of study,
+ "Nx1", referring the manager of the department (n+1 of the responsible of study),
+ "Nx2", referring the boss of the department manager (n+2 of the responsible of study),
+ "customer" (most likely involved in the acceptance step).
+ -->
+ <validations>
+ <specification review="Nx1" approval="Nx2"/>
+ <report review="Nx1" approval="Nx2"/>
+ <default review="manager" />
+ </validations>
+
+</workflow>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+ <!-- Database connection settings -->
+ <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
+ <property name="connection.url">jdbc:mysql://localhost/simer</property>
+ <property name="connection.username">simer</property>
+ <property name="connection.password">admin</property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+ <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
+
+ <!-- SQL dialect -->
+ <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property name="current_session_context_class">thread</property>
+
+ <!-- Echo all executed SQL statements to stdout -->
+ <property name="hibernate.show_sql">false</property>
+
+ <!-- mapping files -->
+ <mapping resource="org/splat/kernel/Persistent.hbm.xml" />
+ <mapping resource="org/splat/kernel/Any.hbm.xml" />
+ <mapping resource="org/splat/kernel/Entity.hbm.xml" />
+ <mapping resource="org/splat/kernel/Attribute.hbm.xml" />
+ <mapping resource="org/splat/kernel/Relation.hbm.xml" />
+ <mapping resource="org/splat/kernel/IDPool.hbm.xml" />
+ <mapping resource="org/splat/kernel/TextAttribute.hbm.xml" />
+ <mapping resource="org/splat/kernel/Text.hbm.xml" />
+ <mapping resource="org/splat/kernel/User.hbm.xml" />
+
+ <mapping resource="org/splat/som/ProjectElement.hbm.xml" />
+ <mapping resource="org/splat/som/Study.hbm.xml" />
+ <mapping resource="org/splat/som/Scenario.hbm.xml" />
+ <mapping resource="org/splat/som/Attributes.hbm.xml" />
+ <mapping resource="org/splat/som/Relations.hbm.xml" />
+ <mapping resource="org/splat/som/File.hbm.xml" />
+ <mapping resource="org/splat/som/Document.hbm.xml" />
+ <mapping resource="org/splat/som/Publication.hbm.xml" />
+ <mapping resource="org/splat/som/ValidationCycle.hbm.xml" />
+ <mapping resource="org/splat/som/Timestamp.hbm.xml" />
+ <mapping resource="org/splat/som/SimulationContext.hbm.xml" />
+ <mapping resource="org/splat/som/KnowledgeElement.hbm.xml" />
+ <mapping resource="org/splat/som/IDBuilder.hbm.xml" />
+
+ </session-factory>
+
+</hibernate-configuration>
\ No newline at end of file
--- /dev/null
+### direct log messages to stdout ###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+### set log levels - for more verbose logging change 'info' to 'debug' ###
+
+log4j.rootLogger=debug, stdout
+
+log4j.logger.org.hibernate=info
+#log4j.logger.org.hibernate=debug
+
+### log HQL query parser activity
+#log4j.logger.org.hibernate.hql.ast.AST=debug
+
+### log just the SQL
+log4j.logger.org.hibernate.SQL=debug
+
+### log JDBC bind parameters ###
+log4j.logger.org.hibernate.type=info
+#log4j.logger.org.hibernate.type=trace
+
+### log schema export/update ###
+log4j.logger.org.hibernate.tool.hbm2ddl=info
+
+### log HQL parse trees
+#log4j.logger.org.hibernate.hql=debug
+
+### log cache activity ###
+log4j.logger.org.hibernate.cache=info
+
+### log transaction activity
+#log4j.logger.org.hibernate.transaction=debug
+
+### log JDBC resource acquisition
+#log4j.logger.org.hibernate.jdbc=debug
+
+### enable the following line if you want to track down connection ###
+### leakages when using DriverManagerConnectionProvider ###
+#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the root abstract class supporting dynamic attributes.
+ - All objects instance of a subclass of Any are uniquely identified by the rid primary key through the IDGenerator identifier generator class.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.Any" abstract="true">
+
+ <!-- int rid -->
+ <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
+ <generator class="org.splat.kernel.IDGenerator"/>
+ </id>
+
+
+ <!-- Set<Attribute> attributes -->
+ <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Attribute" />
+ </set>
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Abstract root class of persistent objects supporting dynamic attributes.<br/>
+ * Dynamic attributes are instances of concrete subclasses of Attribute that are assigned to Any objects at run time.
+ * The attributes of a given Any object must all be of different types.
+ *
+ * @see Attribute
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.hibernate.Session;
+import org.splat.som.Database;
+
+
+public abstract class Any extends Persistent {
+
+ private Set<Attribute> attributes;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor.
+ protected Any () {
+ }
+// Initialization constructors
+ protected Any (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// --------------------------------------
+ super(oprop);
+ attributes = new HashSet<Attribute>();
+ }
+ protected Any (Attribute... field) {
+// ----------------------------------
+ attributes = new HashSet<Attribute>();
+ for (int i=0; i<field.length; i++) {
+ if (field[i] == null) continue; // Happen when newing an Any object without property
+ if (field[i].getFrom().equals(this)) attributes.add(field[i]);
+ }
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Attribute getAttribute (Class<? extends Attribute> type) {
+// ---------------------------------------------------------------
+ for (Iterator<Attribute> i=attributes.iterator(); i.hasNext(); ) {
+ Attribute field = i.next();
+ if (field.getClass().equals(type)) return field;
+ }
+ return null;
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected boolean removeAttribute (Attribute field) {
+// ---------------------------------------------------
+ for (Iterator<Attribute> i=attributes.iterator(); i.hasNext(); ) {
+ if (!i.next().equals(field)) continue;
+ i.remove();
+ if (this.isSaved()) Database.getSession().update(this);
+ return true;
+ }
+ return false;
+ }
+
+ protected boolean setAttribute (Attribute field) {
+// ------------------------------------------------
+ Class<?> type = field.getClass();
+ Session session = Database.getSession();
+
+ if (!field.getFrom().equals(this)) return false;
+ for (Iterator<Attribute> i=attributes.iterator(); i.hasNext(); ) {
+ if (!i.next().getClass().equals(type)) continue;
+ i.remove();
+ break;
+ }
+ attributes.add(field);
+ if (this.isSaved()) {
+ if (!field.isSaved()) session.save(field);
+ session.update(this);
+ } // Else, when saving this, Hibernate will propagate the operation
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the Attribute class hierarchy.
+ - The attribute hierarchy is mapped to a single table using a String discriminator.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.Attribute" abstract="true" table="attribute">
+
+ <!-- int rid -->
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+ <discriminator column="type" type="string"/>
+
+ <!-- Any owner -->
+ <many-to-one name="owner" column="owner" access="field" not-null="true" />
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @see Any
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+
+public abstract class Attribute extends Persistent {
+
+ protected Any owner;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor.
+ protected Attribute () {
+ }
+// Initialization constructor
+ protected Attribute (Any from) {
+// ------------------------------
+ this.owner = from;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Persistent getFrom () {
+// ----------------------------
+ return owner;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.jdbc.Work;
+import org.apache.log4j.Logger;
+
+
+public abstract class Database {
+
+// private static String CONFIG_FILE = "/hibernate.cfg.xml";
+ private static SessionFactory mySessionFactory = null;
+ protected static IDPool myIDpool = null;
+
+ protected class CreateTables implements Work {
+// -----------------------------------------------
+ protected Statement request;
+
+ public void execute(Connection connex) throws SQLException
+ {
+ request = connex.createStatement();
+
+// Last identifier of Any objects
+ String create = "CREATE TABLE `any` (" +
+ "`rid` int(10) UNSIGNED NOT NULL," +
+ "`version` tinytext NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Relation from entities
+ create = "CREATE TABLE `relation` (" +
+ "`rid` int(10) UNSIGNED NOT NULL," +
+ "`name` tinytext NOT NULL," +
+ "`owner` int(10) NOT NULL," +
+ "`refer` int(10) NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Attribute objects
+ create = "CREATE TABLE `attribute` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`type` tinytext NOT NULL," +
+ "`owner` int(10) NOT NULL," +
+ "`value` int(10) NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Java String objects
+ create = "CREATE TABLE `text` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`value` longtext NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// User and role objects
+ create = "CREATE TABLE `user` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`username` varchar(32) NOT NULL," +
+ "`password` varchar(32)," +
+ "`first` tinytext NOT NULL," +
+ "`last` tinytext NOT NULL," +
+ "`display` tinytext," +
+ "`email` tinytext," +
+ "`organid` tinytext," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+ create = "CREATE TABLE `role` (" +
+ "`username` varchar(32) NOT NULL," +
+ "`role` varchar(32) NOT NULL," +
+ "PRIMARY KEY (`username`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+ }
+ }
+
+ protected final static Logger logger = Logger.getLogger(Database.class);
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public static Session getSession () {
+// -----------------------------------
+ return getInstance().getCurrentSession();
+ }
+
+ public static void close () {
+// ---------------------------
+ if (mySessionFactory != null) mySessionFactory.close();
+ mySessionFactory = null;
+ }
+
+ public static IDPool getIDPool () {
+// ---------------------------------
+ if (myIDpool == null) myIDpool = new IDPool(getSession());
+ return myIDpool;
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected String getSchemaVersion () {
+// ------------------------------------
+ return getIDPool().getSchemaVersion();
+ }
+
+ protected void setIDPoolSize (int size) {
+// ---------------------------------------
+ IDPool.setPoolSize(size);
+ }
+
+ protected void setSchemaVersion (String version) {
+// ------------------------------------------------
+ myIDpool = new IDPool(version);
+ getSession().save(myIDpool);
+ }
+
+// ==============================================================================================================================
+// Private services
+// ==============================================================================================================================
+
+ private static SessionFactory getInstance () {
+// --------------------------------------------
+ if (mySessionFactory == null) {
+ org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration();
+ try {
+ cfg.configure(); // The configuration file (hibernate.cfg.xml)) is supposed to be on the classpath
+ mySessionFactory = cfg.buildSessionFactory();
+ }
+ catch (Exception error) {
+ logger.fatal("Could not initialize the Hibernate configuration, reason:", error);
+ }
+ }
+ return mySessionFactory;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
+import javax.mail.BodyPart;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.log4j.Logger;
+
+
+public class Do {
+
+ public static boolean containsIllicitCharacter (String name) {
+// ------------------------------------------------------------
+ char parse[] = name.toCharArray();
+
+ for (int i=0; i<parse.length; i++) {
+ int k = java.lang.Character.getType(parse[i]);
+ if (k == java.lang.Character.DECIMAL_DIGIT_NUMBER) continue;
+ if (k == java.lang.Character.LOWERCASE_LETTER) continue;
+ if (k == java.lang.Character.UPPERCASE_LETTER) continue;
+ if (k == java.lang.Character.SPACE_SEPARATOR) continue;
+ if (k == java.lang.Character.END_PUNCTUATION) continue;
+ if (k == java.lang.Character.DASH_PUNCTUATION) continue;
+ if (parse[i] == '\'') continue;
+ if (parse[i] == '_') continue;
+ if (parse[i] == '&') continue;
+ if (parse[i] == '.') continue;
+ return true;
+ }
+ return false;
+ }
+
+ public static void copy (File fromFile, File toFile) throws IOException {
+// ----------------------------------------------------
+ if (!fromFile.exists()) throw new IOException("ERROR File copy: no such '" + fromFile.getName() + "' source file.");
+ if (!fromFile.isFile()) throw new IOException("Error File copy: can't copy directory '" + fromFile.getName() + "'.");
+
+ if (toFile.isDirectory()) toFile = new File(toFile, fromFile.getName());
+ if (toFile.exists()) throw new IOException("ERROR File copy: file " + toFile.getName() + " already exist.");
+ else {
+ String parent = toFile.getParent();
+ if (parent == null) throw new IOException("ERROR File copy: destination directory not defined.");
+ File dir = new File(parent);
+ if (!dir.exists()) throw new IOException("ERROR File copy: destination directory " + parent + " doesn't exist.");
+ }
+ FileInputStream from = null;
+ FileOutputStream to = null;
+ try {
+ from = new FileInputStream(fromFile);
+ to = new FileOutputStream(toFile);
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+
+ while ((bytesRead = from.read(buffer)) != -1) to.write(buffer, 0, bytesRead); // write
+
+ from.close();
+ to.close();
+ }
+ catch (IOException e) {
+ throw new IOException();
+ }
+ }
+
+ public static boolean sendMail (User to, String subject, String message, File attachement, Properties mprop) {
+// ------------------------------------------------------------------------------------------------------------
+ if (mprop.getProperty("mail.smtp.host") == null) return false;
+ if (mprop.getProperty("mail.pop3.host") == null) return false;
+ if (mprop.getProperty("mail.from") == null) return false;
+
+ Session mail = Session.getInstance(mprop, null);
+ Logger log = Logger.getLogger(Do.class);
+ try {
+ log.info("Preparation of mail to " + to.toString());
+
+ MimeMessage msg = new MimeMessage(mail);
+ msg.setFrom(); // Address defined in properties at mail.from
+ msg.setRecipients(Message.RecipientType.TO, to.getMailAddress());
+ msg.setSubject(subject);
+
+ BodyPart msgBody = new MimeBodyPart();
+ msgBody.setText(message);
+
+ Multipart multipart = new MimeMultipart();
+ multipart.addBodyPart(msgBody);
+
+ if (attachement != null) {
+ String attachname = attachement.getCanonicalPath();
+
+ msgBody = new MimeBodyPart();
+ DataSource attachment = new FileDataSource(attachname);
+ msgBody.setDataHandler(new DataHandler(attachment));
+ msgBody.setFileName(attachname);
+ multipart.addBodyPart(msgBody);
+ }
+ msg.setContent(multipart);
+ msg.setSentDate(new Date());
+
+ Transport.send(msg);
+ log.info("sent.");
+
+ } catch (MessagingException mex) {
+ log.error("Send mail failed, reason " + mex);
+ return false;
+
+ } catch (IOException mex) {
+ log.error("Send mail failed, reason " + mex);
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class DuplicatePropertyException extends Exception {
+
+ private static final long serialVersionUID = 189342004009382158L;
+
+ public DuplicatePropertyException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the root abstract class supporting relations.
+ -
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.Entity" abstract="true">
+
+ <!-- int rid -->
+ <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
+ <generator class="org.splat.kernel.IDGenerator"/>
+ </id>
+
+
+ <!-- Set<Attribute> attributes -->
+ <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Attribute" />
+ </set>
+
+ <!-- Set<Relation> relations -->
+ <set name="relations" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Relation" />
+ </set>
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Abstract root class of persistent objects supporting relations to other persistent objects.<br/>
+ * Relations are instances of concrete subclasses of Relation that are assigned to Entity objects at run time.<br/>
+ * <br/>
+ * Entity objects also support dynamic attributes provided by the Any class.
+ *
+ * @see Relation
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.hibernate.Session;
+
+
+public abstract class Entity extends Any {
+
+ private Set<Relation> relations;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected Entity () {
+ }
+// Initialization constructor
+ protected Entity (ObjectProperties prop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// ----------------------------------------
+ super(prop);
+ relations = new HashSet<Relation>();
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Relation getFirstRelation (Class<? extends Relation> type) {
+// -----------------------------------------------------------------
+ for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
+ Relation link = i.next();
+ if (link.getClass().equals(type)) return link;
+ }
+ return null;
+ }
+
+ public List<Relation> getRelations (Class<? extends Relation> type) {
+// -------------------------------------------------------------------
+ List<Relation> result = new Vector<Relation>();
+
+ for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
+ Relation link = i.next();
+ if (link.getClass().equals(type)) result.add(link);
+ }
+ return result;
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected Set<Relation> getAllRelations () {
+// ------------------------------------------
+ return relations;
+ }
+
+ protected Relation addRelation (Relation link) {
+// ----------------------------------------------
+ Session session = Database.getSession();
+
+ session.save(link);
+ relations.add(link);
+ session.update(this);
+
+ if (link.isBidirectional()) {
+ Entity to = (Entity)link.getTo(); // Bidirectional relation are necessarily between entities
+
+ link = link.getReverse();
+ session.save(link);
+// if (to.relations == null) to.relations = new HashSet<Relation>();
+ to.relations.add(link);
+ session.update(to);
+ }
+ return link;
+ }
+
+ protected void removeRelation (Class<? extends Relation> type, Persistent to) {
+// -----------------------------------------------------------------------------
+ for (Iterator<Relation> i=relations.iterator(); i.hasNext();) {
+ Relation link = i.next();
+ if (!link.getClass().equals(type)) continue;
+ if (!link.getTo().equals(to)) continue;
+ i.remove();
+ if (this.isSaved()) Database.getSession().update(this);
+ return;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.EnhancedUserType;
+import org.hibernate.usertype.ParameterizedType;
+
+
+public class GenericEnumType implements EnhancedUserType, ParameterizedType {
+
+ @SuppressWarnings("unchecked")
+ private Class<Enum> enumClass;
+
+ @SuppressWarnings("unchecked")
+ public void setParameterValues (Properties parameters) {
+// ------------------------------------------------------
+ String enumClassName = parameters.getProperty("enumClassName");
+ try {
+ enumClass = (Class<Enum>) Class.forName(enumClassName);
+ }
+ catch (ClassNotFoundException cnfe) {
+ throw new HibernateException("Enum class not found", cnfe);
+ }
+ }
+
+ public Object assemble (Serializable cached, Object owner) throws HibernateException {
+// ----------------------------------------------------------
+ return cached;
+ }
+
+ public Object deepCopy (Object value) throws HibernateException {
+// -------------------------------------
+ return value;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Serializable disassemble (Object value) throws HibernateException {
+// ----------------------------------------------
+ return (Enum) value;
+ }
+
+ public boolean equals (Object x, Object y) throws HibernateException {
+// ------------------------------------------
+ return x==y;
+ }
+
+ public int hashCode (Object x) throws HibernateException {
+// ------------------------------
+ return x.hashCode();
+ }
+
+ public boolean isMutable () {
+// ---------------------------
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object nullSafeGet (ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+// ----------------------------------------------------------------------
+ String name = rs.getString( names[0] );
+ return rs.wasNull() ? null : Enum.valueOf(enumClass, name);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void nullSafeSet (PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+// -----------------------------------------------------------------------
+ if (value==null) {
+ st.setNull(index, Types.CHAR);
+ }
+ else {
+ st.setString( index, ( (Enum) value ).name() );
+ }
+ }
+
+ public Object replace (Object original, Object target, Object owner) throws HibernateException {
+// --------------------------------------------------------------------
+ return original;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class returnedClass () {
+// -----------------------------
+ return enumClass;
+ }
+
+ public int[] sqlTypes () {
+// ------------------------
+ return new int[] { Types.CHAR };
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object fromXMLString (String xmlValue) {
+// ---------------------------------------------
+ return Enum.valueOf(enumClass, xmlValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ public String objectToSQLString (Object value) {
+// ----------------------------------------------
+ return '\'' + ( (Enum) value ).name() + '\'';
+ }
+
+ @SuppressWarnings("unchecked")
+ public String toXMLString (Object value) {
+// ----------------------------------------
+ return ( (Enum) value ).name();
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Class generating the persistent identifier of all objects instance of a subclass of Any.<br/>
+ * The implementation of this generator is optimized basing on IDPool.
+ *
+ * @see IDPool
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.IdentifierGenerator;
+
+
+public class IDGenerator implements IdentifierGenerator {
+
+ public Serializable generate (SessionImplementor session, Object any) throws HibernateException {
+// ---------------------------------------------------------------------
+ return Database.getIDPool().getNextID();
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.IDPool" table="any">
+
+
+ <id name="lastid" column="rid" access="field">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="version" column="version" access="field" not-null="true" />
+
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Optimized generator of persistent identifiers.<br/>
+ * This generator minimizes the database hits by grouping a bunch of identifiers in memory and only hitting the database
+ * when the in-memory value group is exhausted.
+ * Only one IDPool object held by the Database class is created during a session.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.hibernate.Session;
+import org.hibernate.jdbc.Work;
+
+
+public class IDPool {
+
+// Persistent fields
+ private Integer lastid; // Last generated ID
+ private String version; // Version of the database schema
+
+// Transient fields
+ private int remaining; // Remaining available ID held in this pool
+ private static int poolsize = 1; // No pool by default
+
+ private class LoadNewIDs implements Work {
+// -----------------------------------------
+ public void execute(Connection connex) throws SQLException
+ {
+ Statement request = connex.createStatement();
+ ResultSet result = request.executeQuery("SELECT MAX(rid) AS lastid FROM any");
+ StringBuffer command = new StringBuffer("UPDATE any SET rid=");
+
+ result.first();
+ lastid = result.getInt("lastid");
+
+ command.append(lastid + poolsize).append(" WHERE rid=").append(lastid);
+ request.execute(command.toString());
+
+ remaining = poolsize;
+ }
+ }
+ private class LoadLastID implements Work {
+// -----------------------------------------
+ public void execute(Connection connex) throws SQLException
+ {
+ Statement request = connex.createStatement();
+ ResultSet result = request.executeQuery("SELECT MAX(rid) AS lastid FROM any");
+ StringBuffer command = new StringBuffer("SELECT version FROM any WHERE rid=");
+
+ result.first();
+ lastid = result.getInt("lastid");
+
+ command.append(lastid);
+ result = request.executeQuery(command.toString());
+ result.first();
+ version = result.getString("version");
+ remaining = 0;
+ }
+ }
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+ protected IDPool () {
+ }
+/**
+ * Constructor called only once, when initializing the database.
+ *
+ * @param version the version of the constructed database schema.
+ */
+ protected IDPool (String version) {
+// ---------------------------------
+ this.lastid = 0; //TODO: Get the current last ID if a previous version exists
+ this.version = version;
+ this.remaining = 0;
+ }
+/**
+ * Constructor called at start of every database session.
+ *
+ * @param base the started database session
+ */
+ protected IDPool (Session base) {
+// -------------------------------
+ base.doWork( new LoadLastID() );
+ }
+
+// ==============================================================================================================================
+// Protected member functions
+// ==============================================================================================================================
+
+ protected Integer getNextID () {
+// ------------------------------
+ if (remaining <= 0) Database.getSession().doWork( new LoadNewIDs() );
+ lastid += 1;
+ remaining -= 1;
+ return lastid;
+ }
+
+ protected String getSchemaVersion () {
+// ------------------------------------
+ return version;
+ }
+
+ protected static void setPoolSize (int size) {
+// --------------------------------------------
+ if (size > 1) poolsize = size;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class InvalidPropertyException extends Exception {
+
+ private static final long serialVersionUID = -3988379180445723963L;
+
+ public InvalidPropertyException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class MismatchException extends Exception {
+
+ private static final long serialVersionUID = 366699682058153984L;
+
+ public MismatchException () {
+ }
+ public MismatchException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class MissedPropertyException extends Exception {
+
+ private static final long serialVersionUID = -4459708372517969441L;
+
+ public MissedPropertyException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class MultiplyDefinedException extends Exception {
+
+ private static final long serialVersionUID = 3551033092059904168L;
+
+ public MultiplyDefinedException () {
+ }
+ public MultiplyDefinedException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Interface implemented by the User class for allowing the application to manipulate lists of user names mixing
+ * real users and generic users such as Author of something or Responsible of that.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+
+public interface Name {
+
+ public int getIndex ();
+ public String toString ();
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public class NotApplicableException extends Exception {
+
+ private static final long serialVersionUID = -6255758696740565804L;
+
+ public NotApplicableException (String message) {
+ super(message);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Common interface of intermediate properties objects used for constructing persistent objects supporting the API Design Pattern
+ * provided by this package.
+ * This interface mainly provides a frame for checking the validity of arguments used by persistent object constructors.
+ * The validity check is implemented in classes inheriting from the Persistent.Properties abstract class through the checkValidity
+ * member function defined in this interface - see class User included in this package for an example of use.
+ *
+ * @see Persistent
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+public interface ObjectProperties {
+
+/**
+ * Checks the mutual compatibility of arguments previously set in the properties object.
+ * The validity of each individual argument is supposed to be check first in the setter function of the argument.
+ *
+ * @throws MissedPropertyException
+ * @throws InvalidPropertyException
+ * @throws MultiplyDefinedException
+ */ public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException;
+
+ /**
+ * Disables the validity check.
+ * The validity check is by default enabled when constructing an properties object.
+ */ public void disableCheck ();
+
+ /**
+ * Returns true if the validity check is enabled.
+ */ public boolean mustBeChecked ();
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the primary key common to all Persistent objects.
+ -
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.Persistent" abstract="true">
+
+
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Base implementation of the API Design Pattern of objects which persistence is based on Hibernate.<br/>
+ * This Design Pattern supports the following features:
+ * <ul>
+ * <li>Flexible API for constructing objects from many variable arguments</li>
+ * <li>Impossible to leave persistent objects in inconsistent state, even temporarily, during their construction</li>
+ * <li>Same Object Oriented API for constructing and selecting objects from the database</li>
+ * <li>Centralized validity check of arguments</li>
+ * </ul>
+ * The API is based on intermediate properties objects used for collecting arguments and checking their validity.
+ * These properties objects are passed to persistent object constructors and database select functions for execution.
+ * For example, as based on this Design Pattern, a User object could be created that way:
+ * <pre>
+ * User.Properties args = new User.Properties();
+ * User user = new User( args.setUsername("mypseudo").setMailAddress("me@provider.domain") );
+ * </pre>
+ * Classes implementing this Design Pattern must inherit from Persistent and implement their Properties class as a nested
+ * subclass of Persistent.Properties.<br/>
+ * <br/>
+ * Naturally, as usual with Hibernate, any class can be persistent (you don't need to inherit from Persistent for being
+ * persistent). Inheriting from Persistent is only a matter of enabling the API supported by the above Design Pattern.
+ *
+ * @see ObjectProperties
+ * @see Persistent.Properties
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+
+public abstract class Persistent {
+
+ private int rid; // Primary key of persistent objects
+
+ protected abstract static class Properties implements ObjectProperties {
+// ----------------------------------------------------------------------
+ private boolean tobechecked = true; // Property validity check flag
+
+ public void disableCheck () {
+ tobechecked = false;
+ }
+ public boolean mustBeChecked () {
+ return tobechecked;
+ }
+ public void clear () {
+ tobechecked = true;
+ }
+ }
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+/**
+ * Database fetch constructor.
+ */
+ protected Persistent () {
+// -----------------------
+ rid = 0; // Set when loading the object
+ }
+
+/**
+ * Checks the mutual compatibility of arguments previously set in the given properties object, if the validity check is enabled.
+ * As this validity depends on concrete classes, the check is delegated to subclasses of the given Persistent.Properties.
+ */
+ protected Persistent (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// ---------------------------------------------
+ if (oprop.mustBeChecked()) oprop.checkValidity(); // Throws one of the above exception if not valid
+ rid = 0; // Set when saving the object
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean equals(Object entity) {
+// ------------------------------------
+ if (entity == null) return false;
+ if (entity.getClass().equals(this.getClass())) {
+ Persistent object = (Persistent)entity;
+ int he = object.getIndex(); // getIndex() is supposed fetching the index if not yet done
+ int me = this.getIndex(); // getIndex() is supposed fetching the index if not yet done
+ if (me*he != 0) return (he == me);
+ if (me+he == 0) return (this == object);
+ }
+ return false;
+ }
+
+/**
+ * Returns the Persistent ID of this object. The PID is set when saving this object. It is unique in the scope of the class
+ * of this object only.
+ *
+ * @return the PID of this, or 0 if this is not saved.
+ * @see isSaved()
+ */
+ public int getIndex () {
+// ----------------------
+ return rid;
+ }
+
+ public int hashCode () {
+// ----------------------
+ return toString().hashCode();
+ }
+
+/**
+ * Returns true if this object is saved.
+ *
+ * @return true if this is saved.
+ * @see getIndex()
+ */
+ public boolean isSaved () {
+// -------------------------
+ return (getIndex() != 0); // getIndex() is supposed fetching the index if not yet done
+ }
+
+/**
+ * Return a string representing uniquely this object.
+ *
+ * @return the unique string representation of this object.
+ */
+ public String toString () {
+// -------------------------
+ int oid = getIndex(); // getIndex() is supposed fetching the index if not yet done
+ if (oid == 0) oid = super.hashCode(); //WARNING: Must not call super.toString() as it goes back here (this.toString())
+ return new StringBuffer("object ").append(getClass().getName()).append("@").append(oid).toString();
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Map;
+
+import javax.security.auth.*;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.*;
+import javax.security.auth.spi.*;
+
+import org.apache.log4j.Logger;
+
+
+public class RealmLoginModule implements LoginModule {
+
+// Initial state
+ private Subject subject;
+ private CallbackHandler callbackHandler;
+// private Map sharedState;
+// private Map options;
+
+// Authentication status
+ private boolean succeeded = false;
+ private boolean commit = false;
+
+// Principal
+ private User identity = null;
+
+ private Logger logger = null;
+
+// ==============================================================================================================================
+// Constructor
+// ==============================================================================================================================
+
+ public void initialize(Subject user, CallbackHandler handler, Map<String, ?> state, Map<String, ?> opts) {
+// --------------------------------------------------------------------------------------------------------
+ subject = user;
+ callbackHandler = handler;
+// sharedState = state;
+// options = opts;
+// debug = "true".equalsIgnoreCase((String)options.get("debug"));
+ logger = Logger.getLogger(Database.class);
+ }
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public boolean login() throws LoginException {
+// ----------------------
+ try {
+// Ask for username password
+ Callback[] callbacks = new Callback[2];
+ callbacks[0] = new NameCallback("username");
+ callbacks[1] = new PasswordCallback("password", false);
+
+ callbackHandler.handle(callbacks);
+
+ String username = ((NameCallback)callbacks[0]).getName();
+ String password = null;
+ char[] entered = ((PasswordCallback)callbacks[1]).getPassword();
+ if (entered != null) {
+ password = new String(entered);
+ ((PasswordCallback)callbacks[1]).clearPassword();
+ }
+
+// Authentication
+ User found = UserDirectory.selectUser(username, password);
+ if (found != null) {
+ identity = found;
+ succeeded = true;
+ Calendar today = java.util.Calendar.getInstance();
+ Date datime = today.getTime();
+ logger.info("RKV:Connection of " + identity.toString() + " " + datime.toString() + ".");
+ return true;
+ } else {
+ identity = null;
+ succeeded = false;
+ found = UserDirectory.selectUser(username);
+ String reason = "password";
+ if (found == null) reason = "username";
+ logger.info("Connection attempt as " + username + ".");
+ throw new FailedLoginException(reason);
+ }
+ }
+ catch (java.io.IOException ioe) {
+ throw new LoginException(ioe.toString());
+ }
+ catch (UnsupportedCallbackException uce) {
+ throw new LoginException("Error: " + uce.getCallback().toString() +
+ " not available to garner authentication information" +
+ " from the user");
+ }
+ }
+
+ public boolean commit() throws LoginException {
+// -----------------------
+ if (!succeeded) return false;
+
+ if (!subject.getPrincipals().contains(identity)) subject.getPrincipals().add(identity);
+ identity = null;
+ commit = true;
+ return true;
+ }
+
+ public boolean abort() throws LoginException {
+// ----------------------
+ if (!succeeded) {
+ return false;
+ } else
+ if (succeeded && !commit) {
+ identity = null;
+ succeeded = false;
+ } else {
+ logout();
+ }
+ return true;
+ }
+
+ public boolean logout() throws LoginException {
+// -----------------------
+ subject.getPrincipals().remove(identity);
+ identity = null;
+ succeeded = false;
+ commit = false; // To be validated
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the Relation class hierarchy.
+ - The entire hierarchy is mapped to one single table using a String discriminator.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.Relation" abstract="true" table="relation">
+
+ <!-- int rid -->
+ <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
+ <generator class="org.splat.kernel.IDGenerator"/>
+ </id>
+ <discriminator column="name" type="string"/>
+
+ <!-- Set<Attribute> attributes -->
+ <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Attribute" />
+ </set>
+
+ <!-- Entity owner -->
+ <many-to-one name="owner" column="owner" access="field" not-null="true" />
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Base implementation of relations between entities.<br/>
+ * A relation makes a typed link from an entity to any kind persistent object. The relations are typed by subclasses of this
+ * abstract class which define the actual object referenced by the relation.<br/>
+ * This Relation base class implements unidirectional relations. The bidirectionality must be implemented in concrete subclasses
+ * by:
+ * <ul>
+ * <li>overriding the isBidirectional() and getReverseClass() methods,</li>
+ * <li>creating the reverse relation in constructors.</li>
+ * </ul>
+ * Relation objects also support dynamic attributes provided by the Any class.
+ *
+ * @see Entity
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Iterator;
+
+import org.hibernate.Session;
+
+
+public abstract class Relation extends Any {
+
+// Persistent fields
+ protected Entity owner; // Study or Document
+
+// Transient field
+ protected Relation reverse;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected Relation () {
+// ---------------------
+ reverse = null;
+ }
+// Initialization constructor
+ protected Relation (Entity from) {
+// --------------------------------
+ super((Attribute)null); // For building the collection of attributes
+ this.owner = from;
+ this.reverse = null; // Initialized by subclasses
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Entity getFrom () {
+// ------------------------
+ return owner;
+ }
+
+ public Relation getReverse () {
+// -----------------------------
+ if (!this.isBidirectional() || reverse != null) return reverse;
+
+ Class<? extends Relation> type = this.getReverseClass();
+ Entity to = (Entity)this.getTo(); // Bidirectional relations are necessarily between Entities
+
+ for (Iterator<Relation> i=to.getAllRelations().iterator(); i.hasNext(); ) {
+ Relation asked = i.next();
+ if (!asked.getClass().equals(type)) continue;
+ if (!asked.getTo().equals(owner)) continue;
+ reverse = asked;
+ reverse.reverse = this; // For benefiting from this execution
+ return reverse;
+ }
+ return null;
+ }
+
+ public Class<? extends Relation> getReverseClass () {
+// ---------------------------------------------------
+ return null;
+ }
+
+ public boolean isBidirectional () {
+// ---------------------------------
+ return false;
+ }
+
+/**
+ * Moves this relation from its current owner entity to the given one.
+ *
+ * @param nowner the document to which this relation is moved
+ * */
+ public void moveTo (Entity nowner) {
+// ----------------------------------
+ Session session = Database.getSession();
+
+ this.owner = nowner;
+ nowner.getAllRelations().add(this);
+// myold.getAllRelations().remove(this); Harmful as it leads to remove this relation from the database (!?)
+ session.update(this);
+ session.update(nowner);
+
+ if (this.isBidirectional()) {
+ Relation link = this.getReverse();
+ link.setTo(nowner);
+ session.update(link);
+ }
+ }
+
+// ==============================================================================================================================
+// Abstract functions
+// ==============================================================================================================================
+
+ public abstract Persistent getTo ();
+ protected abstract void setTo (Persistent to); // For the need of the moveTo() method
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Class of objects representing the role of users.
+ * A role is named by an application-dependent string (reason why role names are not defined by an enumeration).
+ * A user may have several roles, user roles being stored into the database as a list of role names separated by a comma.
+ *
+ * @see User
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Vector;
+
+
+public class Role {
+
+ private String username;
+ private String role;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected Role () {
+ }
+// Initialization constructor
+ protected Role (String username, String role) {
+// ---------------------------------------------
+ this.username = username;
+ this.role = role;
+ }
+
+// ==============================================================================================================================
+// Protected member functions
+// ==============================================================================================================================
+
+ protected void addRole (String role) {
+// ------------------------------------
+ this.role = this.role + "," + role;
+ }
+
+ protected Role[] toArray () {
+// ---------------------------
+ String[] name = role.split(",");
+ Vector<Role> role = new Vector<Role>();
+
+ for (int i=0; i<name.length; i++) role.add(new Role(username, name[i]));
+ return role.toArray(new Role[name.length]);
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+// In functions bellow, the role is supposed having previously been extracted as an array.
+
+ public String getName () {
+// ------------------------
+ return role;
+ }
+
+ public boolean is (String name) {
+// -------------------------------
+ return this.role.equals(name);
+ }
+
+ public boolean isSame (Role other) {
+// ----------------------------------
+ return this.role.equals(other.role);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of persistent Java String.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.kernel.Text" table="text" lazy="false">
+
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+ <property name="value" column="value" type="clob" access="field" not-null="true" />
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Class implementing Hibernate-based persistent Java String.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.som.Database;
+
+
+public class Text extends Persistent {
+
+ private String value;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor.
+ protected Text () {
+ }
+// Initialization constructor
+ public Text (String value) {
+// --------------------------
+ this.value = value;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public String getValue () {
+// -------------------------
+ return value;
+ }
+
+ public void setValue (String value) {
+// -----------------------------------
+ this.value = value;
+//RKV if (this.isSaved()) Database.getSession().update(this);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+<!-- <subclass name="org.splat.kernel.TextAttribute" extends="org.splat.kernel.Attribute" discriminator-value="text">-->
+
+ <joined-subclass name="org.splat.kernel.TextAttribute" extends="org.splat.kernel.Attribute" table="text_attr">
+ <key column="rid"/>
+ <!-- <many-to-one name="mytext" column="value" access="field" cascade="all" not-null="true" /> -->
+ <property name="mytext" column="value" type="text" access="field" not-null="true"/>
+
+ </joined-subclass>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+
+public abstract class TextAttribute extends Attribute {
+
+ //private Text mytext;
+ private String mytext;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor.
+ protected TextAttribute () {
+ }
+// Initialization constructor
+ protected TextAttribute (Any from, Text value) {
+// ----------------------------------------------
+ super(from);
+// mytext = value;
+ }
+
+// Initialization constructor
+ protected TextAttribute (Any from, String value) {
+// ----------------------------------------------
+ super(from);
+ mytext = value;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public String getValue () {
+// -------------------------
+ return mytext;
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected void setValue (String value) {
+// --------------------------------------
+ mytext = value;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the User class and its corresponding Role definition.
+ - User and Role are associated by a one-to-one association on the username User foreign key.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+<!-- Class User
+ -->
+ <class name="org.splat.kernel.User" table="user" lazy="false">
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+ <natural-id>
+ <property name="username" column="username" access="field" />
+ <many-to-one name="role" column="username" insert="false" update="false" unique="true" cascade="save-update" access="field" />
+ <property name="email" column="email" access="field" />
+ </natural-id>
+ <property name="password" column="password" access="field" />
+ <property name="first" column="first" access="field" not-null="true" />
+ <property name="last" column="last" access="field" not-null="true" />
+ <property name="display" column="display" access="field" />
+ <property name="organid" column="organid" access="field" />
+ </class>
+
+<!-- Class Role
+ -->
+ <class name="org.splat.kernel.Role" table="role" lazy="false">
+ <id name="username" column="username" access="field">
+ <generator class="assigned"/>
+ </id>
+ <property name="role" column="role" access="field" not-null="true" />
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.security.Principal;
+
+import org.splat.kernel.Persistent;
+
+
+public class User extends Persistent implements Principal, Name {
+
+// Persistent fields
+ @SuppressWarnings("unused")
+ private String password; // Property without getter function
+
+ private String username; // Unique in the user directory
+ private String first;
+ private String last;
+ private String display; // Optional
+ private Role role; // Roles as list (as stored into the database)
+ private String email;
+ private String organid;
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private String username = null;
+ private String password = null;;
+ private String first = null;
+ private String last = null;
+ private String display = null;
+ private Role role = null;
+ private String email = null;
+ private String organid = null;
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ username = null;
+ password = null;;
+ first = null;
+ last = null;
+ display = null;
+ role = null;
+ email = null;
+ organid = null;
+ }
+ public String getOrganizationName () {
+ return organid;
+ }
+ public String getPassword () {
+ return password;
+ }
+ public String getUsername () {
+ return username;
+ }
+// - Property setters
+
+ public Properties addRole (String role) throws InvalidPropertyException
+ {
+ if (role.length() == 0) throw new InvalidPropertyException("role");
+ if (this.role == null) {
+ this.role = new Role(username, role);
+ } else {
+ Role[] curole = this.role.toArray();
+ for (int i=0; i<curole.length; i++) if (curole[i].is(role)) return this;
+ this.role.addRole(role);
+ }
+ return this;
+ }
+ public Properties setDisplayName (String display) throws InvalidPropertyException
+ {
+ if (display.length() == 0) throw new InvalidPropertyException("displayname");
+ this.display = display;
+ return this;
+ }
+ public Properties setFirstName (String first) throws InvalidPropertyException
+ {
+ if (first.length() == 0) throw new InvalidPropertyException("firstname");
+ this.first = first;
+ return this;
+ }
+ public Properties setMailAddress (String address) throws InvalidPropertyException
+ {
+ String[] term = address.split("@"); // Must be of the form x@y
+ if (term.length != 2) throw new InvalidPropertyException("address");
+ term = term[1].split("\\x2E"); // Must be of the form x@y.z
+ if (term.length != 2) throw new InvalidPropertyException("address");
+ this.email = address;
+ return this;
+ }
+ public Properties setName (String last) throws InvalidPropertyException
+ {
+ if (last.length() == 0) throw new InvalidPropertyException("lastname");
+ this.last = last;
+ return this;
+ }
+ public Properties setOrganizationName (String organization) throws InvalidPropertyException
+ {
+ if (organization.length() == 0) throw new InvalidPropertyException("organization");
+ this.organid = organization;
+ return this;
+ }
+ public Properties setPassword (String password) throws InvalidPropertyException
+ {
+ if (password != null) {
+ if (password.length() < 1) throw new InvalidPropertyException("password");
+ this.password = String.valueOf(password.hashCode());
+ }
+ return this;
+ }
+ public Properties setUsername (String username) throws InvalidPropertyException
+ {
+ if (username.length() == 0) throw new InvalidPropertyException("username");
+ this.username = username;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (username == null) throw new MissedPropertyException("username");
+ if (first == null) throw new MissedPropertyException("firstname");
+ if (last == null) throw new MissedPropertyException("lastname");
+ if (role == null) throw new MissedPropertyException("role");
+ if (email == null) throw new MissedPropertyException("email");
+//TODO: Check if username exists
+ }
+ }
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected User () {
+// --------------
+ }
+// Anonymous user supposed not to be saved
+ public User (String name) {
+// -------------------------
+ username = null;
+ password = null;
+ first = null;
+ last = null;
+ display = name;
+ role = null;
+ email = null;
+ organid = null;
+ }
+// New user
+ public User (Properties uprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// ------------------------------
+ super(uprop); // Throws one of the above exception if not valid
+ this.username = uprop.username;
+ this.password = uprop.password;
+ this.first = uprop.first;
+ this.last = uprop.last;
+ this.display = uprop.display;
+ this.role = uprop.role;
+ this.email = uprop.email;
+ this.organid = uprop.organid;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean equals (Object item) {
+// -----------------------------------
+ if (item == null) return false;
+ if (item instanceof String) {
+ return this.username.equals((String)item); // Usernames are unique
+ }
+ else if (item instanceof User) {
+ User given = (User)item;
+ if (isSaved()) return (this.getIndex() == given.getIndex());
+ else return (this.username.equals(given.username)); // Usernames are unique
+ } else {
+ return false;
+ }
+ }
+
+ public String getDisplayName () {
+// -------------------------------
+ if (display == null) return last + " " + first;
+ else return display;
+ }
+
+ public String getFirstName () {
+// -----------------------------
+ return first;
+ }
+
+ public String getMailAddress () {
+// -------------------------------
+ return email;
+ }
+
+ public String getName () {
+// ------------------------
+ return last;
+ }
+
+ public String getOrganizationName () {
+// ------------------------------------
+ return organid;
+ }
+
+ public String getRoleNames () {
+// -----------------------------
+ return role.getName();
+ }
+
+ public Role[] getRoles () {
+// -------------------------
+ return role.toArray();
+ }
+
+ public String getUsername () {
+// ----------------------------
+ return username;
+ }
+
+ public String toString () {
+// -------------------------
+ return last + " " + first;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.kernel;
+/**
+ * Very minimal implementation of the user directory of a company department.<br/>
+ * This directory can include members of the department, the two level hierarchy of these members (their n+1 and n+2 managers),
+ * and all customers of the department.<br/>
+ * The department hierarchy is defined through a hard-coded combination of user role and organization names (see the getManagerOf
+ * function of this class). It is useful for implementing an application workflow requiring such informmation (the n+1 and n+2
+ * managers are usually involved in the validation process).<br/>
+ * <br/>
+ * When needed, a full implementation of the company organization can be adjoin to this class by using user organization names
+ * as reference to departments into this organization. In this context, the function getManagerOf(user) of this class will be
+ * ineffective (it will return null).
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.IOException;
+import java.io.File;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.hibernate.Session;
+import org.splat.manox.XDOM;
+import org.splat.manox.XMLException;
+import org.splat.som.Database;
+import org.w3c.dom.Node;
+import org.apache.log4j.Logger;
+
+
+public class UserDirectory {
+
+ final static Logger logger = Logger.getLogger(UserDirectory.class);
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public static User createUser (User.Properties uprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+// -----------------------------------------------------
+ User nuser = new User(uprop);
+ Session session = Database.getSession();
+ session.save(nuser);
+
+ return nuser;
+ }
+
+ @SuppressWarnings("unchecked") // For the casting List<String>
+ public static Set<User> importUsers (File xfile) throws XMLException, MismatchException, RuntimeException {
+// ------------------------------------------------
+ String[] name = xfile.getName().split("\\x2E"); // Split by '.' (period) character
+ String fext = name[name.length-1];
+ Session session = Database.getSession();
+
+ if (!fext.equals("xml")) throw new MismatchException("filetype");
+ try {
+ DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
+ org.w3c.dom.Document inDoc = dBuilder.parse(xfile);
+ String xtag = inDoc.getDocumentElement().getNodeName();
+ if (!xtag.equals("users")) throw new MismatchException("filetype");
+ org.w3c.dom.NodeList ulist = inDoc.getElementsByTagName("user");
+
+ List<String> result = (List<String>)session.createSQLQuery("SELECT * FROM user").addScalar("username").list();
+ HashSet<String> members = new HashSet<String>();
+ HashSet<User> imported = new HashSet<User>();
+ for (Iterator<String> i=result.iterator(); i.hasNext();) members.add(i.next());
+
+ for (int i=0; i<ulist.getLength(); i++) {
+ HashMap<String, Node> row = XDOM.getNamedChildNodes(ulist.item(i));
+ User.Properties uprop = new User.Properties();
+
+// Mandatory properties
+ String uname = row.get("username").getTextContent();
+ if (members.contains(uname)) continue; // This user already exists
+ uprop.setUsername(uname)
+ .setFirstName(row.get("first").getTextContent())
+ .setName(row.get("last").getTextContent())
+ .setMailAddress(row.get("mail").getTextContent())
+ .addRole(row.get("role").getTextContent()); // Add all roles at a time
+
+// Optional properties
+ org.w3c.dom.Node node = row.get("password");
+ if (node != null) {
+ uprop.setPassword(node.getTextContent());
+ }
+ node = row.get("display");
+ if (node != null) {
+ uprop.setDisplayName(node.getTextContent());
+ }
+ node = row.get("organization");
+ if (node != null) {
+ uprop.setOrganizationName(node.getTextContent());
+ }
+// Addition of the user
+ uprop.disableCheck(); // Existent user already checked above
+ User newser = new User(uprop);
+ session.save(newser);
+ imported.add(newser);
+ }
+ return imported;
+ }
+ catch (IOException error) {
+ throw new XMLException("XML users file not found");
+ }
+ catch (ParserConfigurationException e) {
+ throw new XMLException("XML Organization parser not accessible");
+ }
+ catch (Exception e) {
+ throw new XMLException("XML users file not valid");
+ }
+ }
+
+/**
+ * Returns the manager of the given user.
+ * This function is effective providing that users are defined according to the following conventions:
+ * <ul>
+ * <li>One user is assigned in the organization as Nx1 (n+1 manager of members of the organization)</li>
+ * <li>Another user is assigned in the organization as Nx2 (n+2 manager of members of the organization)</li>
+ * </ul>
+ * If such users do not exit, null is returned.
+ *
+ * @param user the user whose manager is get
+ * @return the manager of the given user, if defined
+ */
+ public static User getManagerOf (User user) {
+// -------------------------------------------
+ User result = null;
+ String orgname = user.getOrganizationName();
+
+ if (orgname.equals("Nx2")) return result;
+ if (orgname.equals("Nx1")) orgname = "Nx2";
+ else {
+ if (user.getRoleNames().equals("customer")) return result;
+ orgname = "Nx1";
+ }
+ try {
+ User.Properties uprop = new User.Properties();
+ List<User> ulist = UserDirectory.selectUsersWhere(uprop.setOrganizationName(orgname));
+ return ulist.get(0); // n+1 and n+2 managers are unique
+ }
+ catch (Exception e) {
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked") // For the casting List<User>
+ public static List<User> selectAllUsers () {
+// ------------------------------------------
+ String query = "from User order by last asc, first asc";
+ return (List<User>)Database.getSession().createQuery(query).list();
+ }
+
+ public static User selectUser (String username) {
+// -----------------------------------------------
+ StringBuffer query = new StringBuffer("from User where username='").append(username).append("'");
+ return (User)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static User selectUser (String username, String password) {
+// ----------------------------------------------------------------
+//WARNING: For not encoding the password here, we better call a selectUsersWhere(User.Properties),
+// but this requires a getPassword in User.Properties nested class.
+ StringBuffer query = new StringBuffer("from User where username='").append(username).append("' and password");
+ if (password == null) query = query.append(" is null");
+ else query = query.append("='").append(String.valueOf(password.hashCode())).append("'");
+
+ return (User)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static User selectUser (int index) {
+// -----------------------------------------
+ StringBuffer query = new StringBuffer("from User where rid='").append(index).append("'");
+ return (User)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<User> selectUsersWhere (User.Properties... uprop) {
+// --------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from User");
+ String separator = " where (";
+ String value;
+
+ for (int i=0; i<uprop.length; i++) {
+
+ value = uprop[i].getOrganizationName();
+ if (value != null) {
+ query = query.append(separator).append(" organid='").append(value).append("'");
+// separator = " and";
+ }
+ separator = ") or (";
+ }
+ query.append(")");
+ return (List<User>)Database.getSession().createQuery(query.toString()).list();
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Base implementation of actor relations such as Contributor, Reviewer and Approver.
+ * ActorRelation objects are attached to Documents for defining those who HAVE CONTRIBUTED to these documents,
+ * while instances of subclasses of ActorRelation are attached to Studies for setting those who CAN CONTRIBUTE to given document types.</br>
+ * </br>
+ * Depending on the actual relation object, the value of the actor relation has different meaning:
+ * <ul>
+ * <li>The description of ActorRelation objects defines the type of contributions (Contributor, Reviewer, Approver...)</li>
+ * <li>The description of instances of subclasses of ActorRelation defines the type of acting documents</li>
+ * </ul>
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+import org.splat.kernel.User;
+
+
+public abstract class ActorRelation extends Relation {
+
+ private User refer;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected ActorRelation () {
+ }
+// ActorRelation subclasses constructor
+ protected ActorRelation (Study from, User to) {
+// ---------------------------------------------
+ super(from);
+ this.refer = to;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ @Override
+ public User getTo () {
+// --------------------
+ return refer;
+ }
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (User)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.splat.kernel.Role;
+import org.splat.kernel.User;
+
+
+public class ApplicationRights {
+
+ private User user;
+ private Set<String> roles;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+ public ApplicationRights (User user) { // Warning: user may be null
+// ------------------------------------
+ this.roles = new HashSet<String>();
+ this.user = user;
+ if (user != null) {
+ Role[] role = user.getRoles();
+ for (int i=0; i<role.length; i++) {
+ String iam = role[i].getName();
+ roles.add(iam);
+ }
+ }
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean canCreateStudy () {
+// --------------------------------
+ if (user != null) {
+ String position = user.getOrganizationName();
+ if (position != null && position.equals("Nx2")) return false;
+ }
+ return roles.contains(Profile.manager.toString());
+ }
+
+ public boolean canContributeToStudy () {
+// --------------------------------------
+ if (user != null) {
+ String position = user.getOrganizationName();
+ if (position != null && (position.equals("Nx1") || position.equals("Nx2"))) return false;
+ }
+ return (roles.contains(Profile.manager.toString()) || roles.contains(Profile.studengineer.toString()));
+ }
+
+ public boolean canValidate () {
+// -----------------------------
+ return roles.contains(Profile.manager.toString());
+ }
+
+ public boolean canManageKnowledges () {
+// -------------------------------------
+ if (user != null) {
+ String position = user.getOrganizationName();
+ if (position != null && position.equals("Nx2")) return false;
+ }
+ return roles.contains(Profile.knowledgineer.toString());
+ }
+
+ public boolean canManageDatabase () {
+// -----------------------------------
+ if (user != null) {
+ String position = user.getOrganizationName();
+ if (position != null && position.equals("Nx2")) return false;
+ }
+ return roles.contains(Profile.sysadmin.toString());
+ }
+
+// ==============================================================================================================================
+// Getters
+// ==============================================================================================================================
+
+ public User getUser () {
+// ----------------------
+ return user; // May be null
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the Attribute concrete subclasses.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+<!-- Description attribute
+ -->
+ <subclass name="org.splat.som.DescriptionAttribute" extends="org.splat.kernel.TextAttribute" discriminator-value="description">
+ </subclass>
+
+<!-- Comment attribute
+ -->
+ <subclass name="org.splat.som.CommentAttribute" extends="org.splat.kernel.TextAttribute" discriminator-value="comment">
+ </subclass>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Attribute class of type Comment.<br/>
+ * A comment is made of any text up to 65 thousand characters.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Text;
+import org.splat.kernel.TextAttribute;
+
+
+public class CommentAttribute extends TextAttribute {
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor.
+ protected CommentAttribute () {
+ }
+/**
+ * Constructs a comment attached to a time stamp.
+ *
+ * @param from the time stamp to which this comment is attached.
+ * @param value the text of this comment
+ */
+ protected CommentAttribute (Timestamp from, String value) {
+// ---------------------------------------------------------
+ super(from, value);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.User;
+
+
+public class ContributorRelation extends ActorRelation {
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected ContributorRelation () {
+ }
+// Initialization constructor
+ protected ContributorRelation (Study from, User to) {
+// --------------------------------------------------
+ super(from, to);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+
+
+public class ConvertsRelation extends Relation {
+
+// Persistent field
+ private File refer;
+
+// Transient fields
+ private boolean got; // For optimizing getDescription()
+ private String description; // Null if this is not described
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected ConvertsRelation () {
+// -----------------------------
+ got = false;
+ description = null;
+ }
+// Initialization constructors
+ protected ConvertsRelation (Document from, File to) {
+// ---------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.got = true;
+ this.description = null; // Conversion not described
+ }
+ protected ConvertsRelation (Document from, File to, String description) {
+// -----------------------------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.got = true;
+ this.description = description; // May be null
+ if (description != null) this.setAttribute( new DescriptionAttribute(this, description) );
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public String getDescription () {
+// -------------------------------
+ if (!got) {
+ DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
+ if (field != null) description = field.getValue();
+ got = true; // Don't need to be modified later as set and remove attribute functions are private to this class
+ }
+ return description; // May be null
+ }
+
+ public File getTo () {
+// --------------------
+ return refer;
+ }
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (File)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.jdbc.Work;
+import org.apache.log4j.Logger;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanFilter;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.FilterClause;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TermsFilter;
+import org.apache.lucene.search.TopFieldDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+
+import org.splat.kernel.User;
+import org.splat.kernel.UserDirectory;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+
+
+public class Database extends org.splat.kernel.Database {
+
+ private int uplevel = 0; // Level of database upgrade
+ private String basepath = null; // Path of the root directory of repository
+
+ private static Database my = null; // Singleton instance
+
+ protected class CreateTables extends org.splat.kernel.Database.CreateTables {
+// ---------------------------------------------------------------------------
+ public void execute(Connection connex) throws SQLException
+ {
+ super.execute(connex);
+
+// Study Entity
+ String create = "CREATE TABLE `study` (" +
+ "`rid` int(10) UNSIGNED NOT NULL," +
+ "`sid` tinytext NOT NULL," +
+ "`title` tinytext NOT NULL," +
+ "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED', 'TEMPLATE') NOT NULL default 'inWORK'," +
+ "`area` enum('PRIVATE','PUBLIC','REFERENCE') NOT NULL default 'PRIVATE'," +
+ "`manager` int(10) NOT NULL," +
+ "`version` tinytext NOT NULL," +
+ "`docount` int(10) UNSIGNED NOT NULL," +
+ "`history` int(10) UNSIGNED NOT NULL," +
+ "`credate` date NOT NULL," +
+ "`lasdate` date NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Scenario Entity
+ create = "CREATE TABLE `scenario` (" +
+ "`rid` int(10) UNSIGNED NOT NULL," +
+ "`sid` int(10) UNSIGNED NOT NULL," +
+ "`owner` int(10) NOT NULL," +
+ "`scendex` int(3) NOT NULL," +
+ "`title` tinytext NOT NULL," +
+ "`manager` int(10) NOT NULL," +
+ "`cuser` int(10)," +
+ "`credate` date NOT NULL," +
+ "`lasdate` date NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Document Entity and document tag (Publication)
+ create = "CREATE TABLE `document` (" +
+ "`rid` int(10) UNSIGNED NOT NULL," +
+ "`did` tinytext NOT NULL," +
+ "`type` int(10) NOT NULL," +
+ "`step` int(10) NOT NULL," +
+ "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED','EXTERN') NOT NULL default 'inWORK'," +
+ "`name` tinytext NOT NULL," +
+ "`author` int(10) NOT NULL," +
+ "`version` tinytext," +
+ "`countag` int(10) UNSIGNED NOT NULL," +
+ "`history` int(10) NOT NULL," +
+ "`myfile` int(10) NOT NULL," +
+ "`lasdate` date NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+ create = "CREATE TABLE `doctag` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`doc` int(10) NOT NULL," +
+ "`owner` int(10) NOT NULL," +
+ "`isnew` char(1) NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+// Document types
+ create = "CREATE TABLE `doctype` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`name` tinytext NOT NULL," +
+ "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
+ "`step` tinytext NOT NULL," +
+ "`result` tinytext," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+// Document types dependencies
+ create = "CREATE TABLE `docuse` (" +
+ "`owner` int(10) NOT NULL," +
+ "`rid` int(10) NOT NULL" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// ValidationCycle related object
+ create = "CREATE TABLE `cycle` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`type` int(10) NOT NULL," +
+ "`publisher` int(10)," +
+ "`reviewer` int(10)," +
+ "`approver` int(10)," +
+ "`signatory` int(10)," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Timestamp related object
+ create = "CREATE TABLE `stamp` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`type` enum('PROMOTION','REVIEW','APPROVAL','ACCEPTANCE','DISTRIBUTION','REFUSAL') NOT NULL," +
+ "`author` int(10) NOT NULL," +
+ "`date` datetime NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// KnowledgeElements objects
+ create = "CREATE TABLE `knowelm` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`type` int(10) NOT NULL," +
+ "`owner` int(10) NOT NULL," +
+ "`state` enum('inWORK','inDRAFT','inCHECK','APPROVED') NOT NULL default 'inDRAFT'," +
+ "`title` tinytext NOT NULL," +
+ "`value` text NOT NULL," +
+ "`author` int(10) NOT NULL," +
+ "`date` date NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+// KnowledgeElement types
+ create = "CREATE TABLE `knowtype` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`name` tinytext NOT NULL," +
+ "`state` enum('inWORK','inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// SimulationContext objects
+ create = "CREATE TABLE `contelm` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`type` int(10) NOT NULL," +
+ "`step` int(10) NOT NULL," +
+ "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
+ "`value` text NOT NULL," +
+ "`counter` int(10) UNSIGNED NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+// SimulationContext types
+ create = "CREATE TABLE `contype` (" +
+ "`rid` int(10) UNSIGNED NOT NULL auto_increment," +
+ "`name` tinytext NOT NULL," +
+ "`state` enum('inCHECK','APPROVED') NOT NULL default 'inCHECK'," +
+ "`step` int(10) NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Many-to-many association between ProjectElement (Study and Scenario) and SimulationContext
+ create = "CREATE TABLE `projext` (" +
+ "`owner` int(10) NOT NULL," +
+ "`ordex` int(10) NOT NULL," +
+ "`rid` int(10) NOT NULL" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// File objects
+ create = "CREATE TABLE `file` (" +
+ "`rid` int(10) UNSIGNED NOT NULL," +
+ "`format` tinytext NOT NULL," +
+ "`path` tinytext NOT NULL," +
+ "`date` date NOT NULL," +
+ "PRIMARY KEY (`rid`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+
+// Reference objects
+ create = "CREATE TABLE `refid` (" +
+ "`cycle` int(10) NOT NULL," +
+ "`base` int(10) NOT NULL," +
+ "PRIMARY KEY (`cycle`)" +
+ ") ENGINE=MyISAM DEFAULT CHARSET=latin1";
+ request.execute(create);
+ }
+ }
+ protected class CheckVersion implements Work {
+// --------------------------------------------
+ public void execute(Connection connex) throws SQLException
+ {
+ DatabaseMetaData dbmdata = connex.getMetaData();
+ String dbname = "simer"; //TODO: Get the name from meta-data
+ ResultSet table;
+
+ table = dbmdata.getTables(dbname, null, "study", null);
+ if (table.next()) return;
+ uplevel = -1; // Database not initialized
+ }
+ }
+
+ protected final static Logger logger = org.splat.kernel.Database.logger;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+ public static Database getMe () {
+// -------------------------------
+ if (my == null) try {
+ my = new Database();
+ }
+ catch (Exception error) {
+ logger.fatal("Could not access the database, reason:", error);
+ }
+ return my;
+ }
+ private Database () {
+// -------------------
+ Database.getSession().doWork(new CheckVersion());
+ this.setIDPoolSize(4); // Average number of generated IDs when creating a study and versioning a document
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean isInitialized () {
+// -------------------------------
+ return (uplevel >= 0);
+ }
+
+ public void initialize () throws IOException, SQLException {
+// -------------------------
+ logger.info("Creation of the database.");
+
+// Creation of the Lucene index
+ Index.create(); // May throw IOException if the index repository is improperly configured
+
+// Creation of the SIMER SQL tables
+ Session session = Database.getSession();
+ session.doWork(new CreateTables()); // May throw SQLException if the SIMER database does not exist
+ session.flush();
+
+// Population of the database with customized data
+ this.populate();
+
+ session.flush();
+ uplevel = 0; // The database is now up-to-date
+ }
+
+// ==============================================================================================================================
+// Protected member functions
+// ==============================================================================================================================
+
+ protected void configure (Properties reprop) {
+// --------------------------------------------
+ basepath = reprop.getProperty("repository");
+ }
+
+ protected void populate () {
+// --------------------------
+ try {
+// Initialization of the schema version
+ this.setSchemaVersion("D0.3"); //TODO: Get the version name from the configuration file
+
+// Creation of the default system administrator
+//TODO: Get the username password from the Hibernate configuration
+ User.Properties uprop = new User.Properties();
+ uprop.setUsername("simer")
+ .setPassword("admin")
+ .setName("Simulation")
+ .setFirstName("Manager")
+ .setDisplayName("label.sysadmin")
+ .addRole("sysadmin")
+ .setMailAddress("noreply@salome-platform.org");
+ uprop.disableCheck();
+ UserDirectory.createUser(uprop);
+ }
+ catch (Exception e) {
+// Let's continue, hoping the best...
+ }
+ ProjectSettings.getMe().initialize(); // Populates the database with all necessary stuff
+ }
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public static Study createStudy (Study.Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+// --------------------------------------------------------
+ Study study = new Study(sprop);
+
+ study.buildReference();
+ Database.getSession().save(study);
+ try {
+ Index lucin = getIndex();
+ lucin.add(study);
+ }
+ catch (IOException error) {
+ logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
+// Continue and try to index later
+ }
+ return study;
+ }
+
+ public static void indexStudy (Study study) {
+// -------------------------------------------
+ try {
+ Study.Properties sprop = new Study.Properties();
+ List<Proxy> index = Database.selectStudiesWhere(sprop.setReference(study.getReference()));
+
+ if (index.size() != 0) return; // The given study is already indexed
+
+ Index lucin = getIndex();
+ Scenario[] scenes = study.getScenarii();
+
+ lucin.add(study);
+ if (study.getProgressState() != ProgressState.inWORK) for (int i=0; i<scenes.length; i++) {
+ List<KnowledgeElement> list = scenes[i].getAllKnowledgeElements();
+ for (Iterator<KnowledgeElement> j=list.iterator(); j.hasNext(); ) {
+ lucin.add(j.next());
+ }
+ }
+ }
+ catch (Exception error) {
+ logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
+ }
+ }
+
+ public static Index getIndex () throws IOException {
+// -------------------------------
+ Index lucin = new Index();
+ if ( !lucin.exists() ) Index.create(); // Happens when re-indexing all studies
+ return lucin;
+ }
+
+ public static File getDownloadDirectory (User user) {
+// ---------------------------------------------------
+ StringBuffer path = new StringBuffer(my.basepath).append("downloads/").append(user.getUsername()).append("/");
+ return new File(path.toString());
+ }
+
+ public static File getRepositoryIndexDirectory () {
+// -------------------------------------------------
+ return new File(my.basepath + "lucin/");
+ }
+
+ public static String getRepositoryVaultPath () {
+// --------------------------------------------
+ return (my.basepath + "vault/");
+ }
+
+ public static String getTemplatePath () {
+// ---------------------------------------
+ return (my.basepath + "templates/");
+ }
+
+ public static Document selectDocument (int index) {
+// -------------------------------------------------
+ StringBuffer query = new StringBuffer("from Document where rid='").append(index).append("'");
+ return (Document)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static Document selectDocument (String refid, String version) {
+// --------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from Document where did='").append(refid).append("' and version='").append(version).append("'");
+ return (Document)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static KnowledgeElement selectKnowledgeElement (int index) {
+// -----------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from KnowledgeElement where rid='").append(index).append("'");
+ KnowledgeElement result = (KnowledgeElement)Database.getSession().createQuery(query.toString()).uniqueResult();
+
+ result.getOwnerScenario().getOwnerStudy().loadWorkflow();
+ return result;
+ }
+
+ public static List<Proxy> selectKnowledgeElementsWhere (KnowledgeElement.Properties... kprop) {
+// ---------------------------------------------------------------------------------------------
+ List<Proxy> result = new ArrayList<Proxy>();
+ int hitsize = 20;
+ try {
+
+// Creation of the Lucene query
+ File indir = Database.getRepositoryIndexDirectory();
+ Directory index = FSDirectory.open(indir);
+ IndexSearcher searcher = new IndexSearcher(index, true);
+ BooleanQuery fulquery = new BooleanQuery();
+
+ for (int i=0; i<kprop.length; i++) {
+ BooleanQuery query = new BooleanQuery();
+ Term input; // Supposed initialized below at least by the visibility
+
+ Visibility area = kprop[i].getVisibility(); // Visibility
+ if (area != null) {
+ input = new Term("area");
+ query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
+ }
+ ProgressState state = kprop[i].getProgressState(); // State
+ if (state != null) {
+ input = new Term("state");
+ query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
+ }
+ String refid = kprop[i].getReference(); // Reference
+ if (refid != null) {
+ input = new Term("ref");
+ query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
+ }
+ KnowledgeElementType type = kprop[i].getType(); // Type
+ if (type != null) {
+ input = new Term("type");
+ query.add(new TermQuery(input.createTerm(type.getName())), BooleanClause.Occur.MUST);
+ }
+ User manager = kprop[i].getAuthor(); // Author
+ if (manager != null) {
+ input = new Term("author");
+ query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
+ }
+ User actor = kprop[i].getActor(); // Contributor, Reviewer or Approver of the owner study
+ if (actor != null) {
+ input = new Term("actor");
+ query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
+ }
+ String title = kprop[i].getTitle(); // Title
+ if (title != null) {
+ input = new Term("contents");
+ BooleanQuery critext = new BooleanQuery();
+ String operator = "AND"; // Future user input
+ BooleanClause.Occur clause = BooleanClause.Occur.MUST;
+ if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
+ String[] word = title.split(" ");
+ for (int j=0; j<word.length; j++) {
+ critext.add(new TermQuery(input.createTerm(word[j])), clause);
+ }
+ query.add(critext, BooleanClause.Occur.MUST);
+ }
+ List<SimulationContext> context = kprop[i].getSimulationContexts();
+ if (context != null && context.size() > 0) {
+ BooleanQuery critext = new BooleanQuery();
+ for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
+ SimulationContext seltext = j.next();
+ input = new Term(String.valueOf(seltext.getType().getIndex()));
+ critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
+ }
+ query.add(critext, BooleanClause.Occur.MUST);
+ }
+ fulquery.add(query, BooleanClause.Occur.SHOULD);
+ }
+ if (logger.isInfoEnabled()) {
+ logger.info("Searching knowledges by Lucene query \"" + fulquery.toString() + "\".");
+ }
+// Creation of the knowledge filter
+ BooleanFilter filter = new BooleanFilter();
+ TermsFilter select = new TermsFilter();
+ Term mytype = new Term("class");
+ select.addTerm( mytype.createTerm("KnowledgeElement") );
+ filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
+
+// Creation of the sort criteria
+ Sort sort = new Sort(new SortField("title", SortField.STRING));
+
+// Search
+ TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
+
+ if (found.totalHits < 1) return result; // No study found
+
+// Construction of the result list
+ ScoreDoc[] hits = found.scoreDocs;
+ for (int i=0; i<hits.length; i++) {
+ result.add( new Index.ObjectProxy(searcher.doc(hits[i].doc)) );
+ }
+ searcher.close();
+ }
+ catch (Exception error) {
+ logger.error("Error during Lucene search, reason:", error);
+ }
+ return result;
+ }
+
+ public static SimulationContext selectSimulationContext (int index) {
+// -------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContext where rid='").append(index).append("'");
+ return (SimulationContext)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static SimulationContext selectSimulationContext (SimulationContextType celt, String value) {
+// --------------------------------------------------------------------------------------------------
+ SimulationContext result = null;
+ try {
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ List<SimulationContext> clist = selectSimulationContextsWhere(cprop.setType(celt).setValue(value));
+ if (!clist.isEmpty()) result = clist.get(0); // Supposed being the most used one if many exist
+ }
+ catch (InvalidPropertyException error) {
+ logger.info("Attempt to select a simulation context \"" + celt.getName() + "\" with an invalid value.");
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<SimulationContext> selectSimulationContextsWhere (SimulationContext.Properties cprop) {
+// --------------------------------------------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContext");
+ String separator = " where";
+ SimulationContextType celt = cprop.getType();
+ String value = cprop.getValue();
+ ProgressState state = cprop.getProgressState();
+ String order = "";
+
+ if (celt != null) { query = query.append(separator).append(" type='").append(celt.getIndex()).append("'");
+ separator = " and";
+ order = " order by value asc";
+ }
+ if (value != null ) { query = query.append(separator).append(" value='").append(value).append("'");
+ separator = " and";
+ }
+ if (state != null ) { query = query.append(separator).append(" state='").append(state).append("'");
+ if (celt == null) order = " order by type asc";
+ }
+ query.append(order);
+ return (List<SimulationContext>)Database.getSession().createQuery(query.toString()).list();
+ }
+
+ public static Study selectStudy (int index) {
+// -------------------------------------------
+ StringBuffer query = new StringBuffer("from Study where rid='").append(index).append("'");
+ Study result = (Study)Database.getSession().createQuery(query.toString()).uniqueResult();
+
+ result.loadWorkflow();
+ return result;
+ }
+
+ public static Study selectStudy (String refid) {
+// ----------------------------------------------
+ StringBuffer query = new StringBuffer("from Study where sid='").append(refid).append("'");
+ Study result = (Study)Database.getSession().createQuery(query.toString()).uniqueResult();
+
+ result.loadWorkflow();
+ return result;
+ }
+
+ public static List<Proxy> selectStudiesWhere (Study.Properties... sprop) {
+// ------------------------------------------------------------------------
+ List<Proxy> result = new ArrayList<Proxy>();
+ int hitsize = 20;
+ try {
+
+// Creation of the Lucene query
+ File indir = Database.getRepositoryIndexDirectory();
+ Directory index = FSDirectory.open(indir);
+ IndexSearcher searcher = new IndexSearcher(index, true);
+ BooleanQuery fulquery = new BooleanQuery();
+
+ for (int i=0; i<sprop.length; i++) {
+ BooleanQuery query = new BooleanQuery();
+ Term input; // Supposed initialized below at least by the visibility
+
+ Visibility area = sprop[i].getVisibility(); // Visibility
+ if (area != null) {
+ input = new Term("area");
+ query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
+ }
+ ProgressState state = sprop[i].getProgressState(); // State
+ if (state != null) {
+ input = new Term("state");
+ if (state == ProgressState.inPROGRESS) {
+ BooleanQuery cristate = new BooleanQuery();
+ cristate.add(new TermQuery(input.createTerm("inWORK")), BooleanClause.Occur.SHOULD);
+ cristate.add(new TermQuery(input.createTerm("inDRAFT")), BooleanClause.Occur.SHOULD);
+ cristate.add(new TermQuery(input.createTerm("inCHECK")), BooleanClause.Occur.SHOULD);
+ query.add(cristate, BooleanClause.Occur.MUST);
+ } else {
+ query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
+ }
+ }
+ String refid = sprop[i].getReference(); // Reference
+ if (refid != null) {
+ input = new Term("ref");
+ query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
+ }
+ User manager = sprop[i].getManager(); // Author
+ if (manager != null) {
+ input = new Term("author");
+ query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
+ }
+ User actor = sprop[i].getActor(); // Contributor, Reviewer or Approver
+ if (actor != null) {
+ input = new Term("actor");
+ query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
+ }
+ String title = sprop[i].getTitle(); // Title
+ if (title != null) {
+ input = new Term("contents");
+ BooleanQuery critext = new BooleanQuery();
+ String operator = "AND"; // Future user input
+ BooleanClause.Occur clause = BooleanClause.Occur.MUST;
+ if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
+ String[] word = title.split(" ");
+ for (int j=0; j<word.length; j++) {
+ critext.add(new TermQuery(input.createTerm(word[j])), clause);
+ }
+ query.add(critext, BooleanClause.Occur.MUST);
+ }
+ List<SimulationContext> context = sprop[i].getSimulationContexts();
+ if (context != null && context.size() > 0) {
+ BooleanQuery critext = new BooleanQuery();
+ for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
+ SimulationContext seltext = j.next();
+ input = new Term(String.valueOf(seltext.getType().getIndex()));
+ critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
+ }
+ query.add(critext, BooleanClause.Occur.MUST);
+ }
+ fulquery.add(query, BooleanClause.Occur.SHOULD);
+ }
+ if (logger.isInfoEnabled()) {
+ logger.info("Searching studies by Lucene query \"" + fulquery.toString() + "\".");
+ }
+// Creation of the studies filter
+ BooleanFilter filter = new BooleanFilter();
+ TermsFilter select = new TermsFilter();
+ Term mytype = new Term("class");
+ select.addTerm( mytype.createTerm("Study") );
+ filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
+
+// Creation of the sort criteria
+ Sort sort = new Sort(new SortField("title", SortField.STRING));
+
+// Search
+ TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
+
+ if (found.totalHits < 1) return result; // No study found
+
+// Construction of the result list
+ ScoreDoc[] hits = found.scoreDocs;
+ for (int i=0; i<hits.length; i++) {
+ result.add( new Index.ObjectProxy(searcher.doc(hits[i].doc)) );
+ }
+ searcher.close();
+ }
+ catch (Exception error) {
+ logger.error("Error during Lucene search, reason:", error);
+ }
+ return result;
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected static IDBuilder selectIDBuilder (int cycle) {
+// ------------------------------------------------------
+ StringBuffer buffer = new StringBuffer("from IDBuilder where cycle='").append(cycle).append("'");
+ String qstring = buffer.toString();
+ Query query = Database.getSession().createQuery(qstring);
+ IDBuilder result = (IDBuilder)query.uniqueResult();
+
+ return result;
+ }
+
+ protected static IDBuilder selectIDBuilder (Date date) {
+// ------------------------------------------------------
+ SimpleDateFormat year = new SimpleDateFormat("yyyy");
+ String cycle = year.format(date);
+ StringBuffer buffer = new StringBuffer("from IDBuilder where cycle='").append(cycle).append("'");
+ String qstring = buffer.toString();
+ Query query = Database.getSession().createQuery(qstring);
+ IDBuilder result = (IDBuilder)query.uniqueResult();
+
+ return result;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Attribute class of type Description.<br/>
+ * A description is made of any text up to 65 thousand characters.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Text;
+import org.splat.kernel.TextAttribute;
+
+
+public class DescriptionAttribute extends TextAttribute {
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor.
+ protected DescriptionAttribute () {
+ }
+/**
+ * Constructs the description of a study or a scenario.
+ *
+ * @param from the study or the scenario to which this description is attached.
+ * @param value the text of this description
+ */
+ protected DescriptionAttribute (ProjectElement from, String value) {
+// ------------------------------------------------------------------
+ super(from, value);
+ }
+/**
+ * Constructs the description attached to a version relation.
+ *
+ * @param from the version relation to which this description is attached.
+ * @param value the text of this description
+ */
+ protected DescriptionAttribute (VersionsRelation from, String value) {
+// --------------------------------------------------------------------
+ super(from, value);
+ }
+ /**
+ * Constructs the description attached to a conversion relation.
+ *
+ * @param from the conversion relation to which this description is attached.
+ * @param value the text of this description
+ */
+ protected DescriptionAttribute (ConvertsRelation from, String value) {
+// --------------------------------------------------------------------
+ super(from, value);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the Document class and its type information implemented by the DocumentType class.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.Document" table="document" lazy="false">
+
+<!-- Properties inherited from Entity
+ -->
+ <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
+ <generator class="org.splat.kernel.IDGenerator"/>
+ </id>
+ <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Attribute" />
+ </set>
+ <set name="relations" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Relation" />
+ </set>
+
+<!-- Document properties
+ -
+ - String did -->
+ <property name="did" column="did" access="field" not-null="true" />
+
+ <!-- DocumentType type -->
+ <many-to-one name="type" column="type" access="field" not-null="true" />
+
+ <!-- File myfile -->
+ <many-to-one name="myfile" column="myfile" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />
+
+ <!-- String name -->
+ <property name="name" column="name" access="field" not-null="true" />
+
+ <!-- ProgressState state -->
+ <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
+
+ <!-- int step -->
+ <property name="step" column="step" access="field" not-null="true" />
+
+ <!-- String version -->
+ <property name="version" column="version" access="field" />
+
+ <!-- int countag -->
+ <property name="countag" column="countag" access="field" not-null="true" />
+
+ <!-- int history -->
+ <property name="history" column="history" access="field" not-null="true" />
+
+ <!-- User author -->
+ <many-to-one name="author" column="author" access="field" not-null="true" />
+
+ <!-- Date lasdate -->
+ <property name="lasdate" column="lasdate" access="field" not-null="true" />
+ </class>
+
+<!-- Class DocumentType
+ -->
+ <class name="org.splat.som.DocumentType" table="doctype" lazy="false">
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+ <property name="name" column="name" access="field" not-null="true" />
+ <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
+ <property name="step" column="step" access="field" not-null="true" />
+ <property name="result" column="result" access="field" />
+ <set name="uses" table="docuse" lazy="false" access="field">
+ <key column="owner" />
+ <many-to-many column="rid" class="org.splat.som.DocumentType" />
+ </set>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.hibernate.Hibernate;
+import org.hibernate.Session;
+
+import org.splat.kernel.NotApplicableException;
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.User;
+import org.splat.manox.Reader;
+import org.splat.manox.Toolbox;
+import org.splat.som.ProjectSettings.FileNaming;
+import org.splat.som.Timestamp.ComparatorByDate;
+
+
+public class Document extends Entity {
+
+// Persistent fields
+ private DocumentType type; // User expendable types
+ private File myfile;
+ private String did;
+ private int step;
+ private ProgressState state;
+ private String name;
+ private String version;
+ private int countag;
+ private int history;
+ private User author;
+ private Date lasdate;
+
+// Transient fields
+ public static String suformat = "00"; // Format of the suffix number of document did and file name
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private DocumentType type = null;
+ private String did = null; // Only for searching from a given reference
+ private ProjectElement owner = null; // Only for constructing a document
+ private ProjectSettings.Step step = null;
+ private ProgressState state = null;
+ private String name = null;
+ protected String format = null;
+ private String version = null;
+ private User author = null;
+ protected Date date = null;
+ private String summary = null; // Only for versioning a document
+ private String path = null; // Only for searching from a given path
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ type = null;
+ did = null;
+ owner = null;
+ step = null;
+ state = null;
+ name = null;
+ format = null;
+ version = null;
+ author = null;
+ date = null;
+ summary = null;
+ path = null;
+ }
+ public Properties copy () {
+ Properties copy = new Properties();
+ copy.type = this.type;
+ copy.did = this.did;
+ copy.owner = this.owner;
+ copy.step = this.step;
+ copy.state = this.state;
+ copy.name = this.name;
+ copy.format = this.format;
+ copy.version = this.version;
+ copy.author = this.author;
+ copy.date = this.date;
+ copy.summary = this.summary;
+ copy.path = this.path;
+ return copy;
+ }
+// - Protected services
+
+ protected User getAuthor () {
+ return author;
+ }
+ protected String getDescription () {
+ return summary;
+ }
+ protected String getLocalPath () {
+ return path;
+ }
+ protected String getReference () {
+ return did;
+ }
+ protected ProjectSettings.Step getStep () {
+ return step;
+ }
+ protected DocumentType getType () {
+ return type;
+ }
+// - Property setters
+
+ public Properties setAuthor (User user)
+ {
+ this.author = user;
+ return this;
+ }
+ public Properties setDate (Date date)
+ {
+ this.date = date;
+ return this;
+ }
+ public Properties setDescription (String summary) throws InvalidPropertyException
+ {
+ if (summary.length() == 0) throw new InvalidPropertyException("description");
+ this.summary = summary;
+ return this;
+ }
+ protected Properties setDocument (Document base)
+ {
+ type = base.type;
+ step = ProjectSettings.getStep(base.step);
+ name = base.name;
+ format = base.getFormat();
+ state = ProgressState.inWORK; // For incrementing the version number at save time
+ version = base.version;
+ return this;
+ }
+ public Properties setExternReference (String ref) throws InvalidPropertyException
+ {
+ if (ref.length() == 0) throw new InvalidPropertyException("reference");
+ if (ref.equals(new Revision().toString())) throw new InvalidPropertyException("reference"); // Internal version number
+ this.version = ref;
+ return this;
+ }
+ public Properties setFormat (String format) throws InvalidPropertyException
+ {
+ if (format.length() == 0) throw new InvalidPropertyException("format");
+ this.format = format;
+ return this;
+ }
+// Required only for passing search arguments
+ public Properties setLocalPath (String path) throws InvalidPropertyException
+ {
+ if (path.length() == 0) throw new InvalidPropertyException("path");
+ this.path = path;
+ return this;
+ }
+ public Properties setName (String name) throws InvalidPropertyException
+ {
+ if (name.length() == 0) throw new InvalidPropertyException("name");
+ this.name = name;
+ return this;
+ }
+ protected Properties setOwner (ProjectElement owner)
+ {
+ this.owner = owner;
+ return this;
+ }
+// Required only for passing search arguments
+ public Properties setReference (String did) throws InvalidPropertyException
+ {
+ if (did.length() == 0) throw new InvalidPropertyException("reference");
+ this.did = did;
+ return this;
+ }
+ public Properties setState (ProgressState state) throws InvalidPropertyException
+ {
+ if (state == ProgressState.inPROGRESS || state == ProgressState.TEMPLATE) throw new InvalidPropertyException("state"); // Non document states
+ this.state = state;
+ return this;
+ }
+ protected Properties setStep (ProjectSettings.Step step)
+ {
+ this.step = step;
+ return this;
+ }
+ public Properties setType (DocumentType type)
+ {
+ this.type = type;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (type == null) throw new MissedPropertyException("type");
+ if (owner == null) throw new MissedPropertyException("owner");
+ if (step == null) throw new MissedPropertyException("step");
+ if (author == null) throw new MissedPropertyException("author");
+ if (format == null) throw new MissedPropertyException("format");
+ if (owner instanceof Study && !step.appliesTo(Study.class)) throw new InvalidPropertyException("step");
+ if (!type.isContentInto(step)) throw new InvalidPropertyException("step");
+ if (state != null && state != ProgressState.EXTERN) {
+// inDRAFT, inCHECK or APPROVED + version = imposed version (future use)
+// inWORK + version = base version incremented at save time (used for versioning)
+ if (version == null) throw new InvalidPropertyException("state");
+ }
+ if (version != null) {
+ if (state == null) state = ProgressState.EXTERN;
+ }
+ }
+ }
+// Database fetch constructor
+ protected Document () {
+ }
+// Internal constructor
+ protected Document (Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// -------------------------------------
+ super(dprop); // Throws one of the above exception if not valid
+ myfile = new File(null, dprop.format, dprop.date); // The path is initialized below
+ type = dprop.type;
+ step = dprop.step.getNumber();
+ name = dprop.name;
+ version = dprop.version;
+ author = dprop.author;
+ countag = 0;
+ history = 0;
+ lasdate = myfile.getDate(); // Today if not defined in the properties
+
+ state = dprop.state;
+ if (state == null) {
+ state = ProgressState.inWORK; // Promoted when saving this document
+ version = new Revision().toString();
+ }
+ Study owner = null;
+ if (dprop.owner instanceof Study) owner = (Study)dprop.owner;
+ else owner = ((Scenario)dprop.owner).getOwnerStudy();
+
+ ProjectSettings.Step step = ProjectSettings.getStep(this.step);
+ SimpleDateFormat tostring = new SimpleDateFormat("yyyy");
+ String year = tostring.format(owner.getDate());
+ if (name == null) { // Newed document
+ this.name = "%n"; // Named later at publication
+ this.history = -1; // Marks the document as undefined for future assignment
+ }
+ String filename = generateEncodedName(owner);
+ String path;
+
+ path = owner.getReference();
+ did = new StringBuffer(path).append(".%").append(suformat).toString(); // Document reference
+ path = new StringBuffer(year).append("/").append(path).append("/").append(step.getPath()) // File path relative to the repository vault
+ .append(filename).append(".").append(myfile.getFormat()) // File name and extension
+ .toString();
+ myfile.changePath(path);
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public File getAttachedFile (String format) {
+// -------------------------------------------
+ List<Relation> exports = getRelations(ConvertsRelation.class);
+
+ for (Iterator<Relation> i=exports.iterator(); i.hasNext(); ) {
+ File export = (File)i.next().getTo();
+ if (export.getFormat().equals(format)) return export;
+ }
+ return null;
+ }
+
+ public User getAuthor () {
+// ------------------------
+ return author;
+ }
+
+ public Date getCreationDate () {
+// ------------------------------
+ return myfile.getDate();
+ }
+
+ public Date getLastModificationDate () {
+// --------------------------------------
+ return lasdate;
+ }
+
+ public String getFormat () {
+// --------------------------
+ return myfile.getFormat();
+ }
+
+ public Document getPreviousVersion () {
+// -------------------------------------
+ Relation previous = getFirstRelation(VersionsRelation.class);
+ if (previous != null) return (Document)previous.getTo();
+ else return null;
+ }
+
+ public ProgressState getProgressState () {
+// ----------------------------------------
+ return state;
+ }
+
+/**
+ * Returns the path where all physical files attached to this document are saved.
+ * This path is relative to the vault of the repository and include the file name, without extension, common
+ * to all physical files attached to this document.
+ *
+ * @return the path of the document
+ */
+ public String getRelativePath () {
+// --------------------------------
+ String[] table = myfile.getRelativePath().split("\\x2E");
+ StringBuffer path = new StringBuffer(table[0]);
+ for (int i=1; i<table.length-1; i++) path.append('.').append(table[i]);
+ return path.toString();
+ }
+
+/**
+ * Returns the global unique reference of this document lineage.
+ * The document reference is common to all versions of the document (versioning a document does not change its reference).
+ * It is made of the owner study reference suffixed by a document identifier unique in the scope of the study.
+ *
+ * @return the document reference
+ */
+ public String getReference () {
+// -----------------------------
+ return did;
+ }
+
+ public java.io.File getSaveDirectory () {
+// ---------------------------------------
+ String mypath = Database.getRepositoryVaultPath() + myfile.getRelativePath();
+ String[] table = mypath.split("/");
+
+// Cutting the filename
+ StringBuffer path = new StringBuffer(table[0]);
+ for (int i=1; i<table.length-1; i++) path = path.append("/").append(table[i]);
+ return new java.io.File(path.append("/").toString());
+ }
+
+ public File getSourceFile () {
+// ----------------------------
+ return myfile;
+ }
+
+/**
+ * Returns the stamps such as review and approval attached to this document, if exist.
+ * If several stamps exist, they are returned in ascending order of dates.
+ *
+ * @return the stamps of the document in ascending order of dates, or an empty array if no stamp exist.
+ */
+ public Timestamp[] getStamps () {
+// -------------------------------
+ Vector<Timestamp> stamps = new Vector<Timestamp>();
+
+ for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
+ Relation link = i.next();
+ if (link instanceof StampRelation) stamps.add( ((StampRelation)link).getTo() );
+ }
+ Timestamp[] result = stamps.toArray( new Timestamp[stamps.size()] );
+ ComparatorByDate bydate = new Timestamp.ComparatorByDate();
+
+ Arrays.sort(result, bydate);
+ return result;
+ }
+
+/**
+ * Returns the title of this document.
+ *
+ * @return the document title, or an empty string is this document is undefined.
+ * @see #isUndefined()
+ */
+ public String getTitle () {
+// -------------------------
+ if (this.isUndefined()) return "";
+ else return name;
+ }
+
+ public DocumentType getType () {
+// ------------------------------
+ return type;
+ }
+
+/**
+ * Returns the version number of this document.
+ * The version number, when exists, is either of the internal form (m.n.s) usable for building a Revision object, or any string
+ * in case of external document (document with EXTERN state).<br/>
+ * <br/>
+ * Note: document slots have a version number equal to "0.0.0".
+ *
+ * @return the version number of this document, or null if this is EXTERN.
+ * @see #isUndefined()
+ */
+ public String getVersion () {
+// ---------------------------
+ return version;
+ }
+
+/**
+ * Returns true if this document is undefined.
+ * An undefined document is a meta-document created for reserving the persistent reference of a new document before saving
+ * (or importing) this later into the repository.
+ * The working copy of a such document may include this reference.
+ *
+ * @see #getTitle()
+ * @see #getVersion()
+ * @see #initialize(Properties)
+ */
+ public boolean isUndefined () {
+// -----------------------------
+ return (history == -1);
+ }
+
+ public boolean isInto (Step container) {
+// --------------------------------------
+ return (step == container.getNumber());
+ }
+
+ public boolean isPublished () {
+// -----------------------------
+ return (countag > 0);
+ }
+
+ public boolean isShared () {
+// --------------------------
+ return (countag + history > 1);
+ }
+
+ public boolean isVersioned () {
+// -----------------------------
+ return (history > 0);
+ }
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public static DocumentType createType (DocumentType.Properties tprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+// ---------------------------------------------------------------------
+//TODO: Check for duplicate definition
+ DocumentType type = new DocumentType(tprop);
+ Session session = Database.getSession();
+ session.save(type);
+
+ return type;
+ }
+
+ public static Properties extractProperties (java.io.File file) {
+// --------------------------------------------------------------
+ Properties fprop = new Properties();
+ Reader tool = Toolbox.getReader(file);
+ String value;
+ if (tool != null) try {
+ value = tool.extractProperty("title");
+ if (value != null) fprop.setName(value);
+
+ value = tool.extractProperty("reference");
+ if (value != null) fprop.setReference(value);
+ }
+ catch (Exception e) {
+ }
+ return fprop;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<DocumentType> selectAllTypes () {
+// --------------------------------------------------
+ String query = "from DocumentType";
+
+ List<DocumentType> types = Database.getSession().createQuery(query).list();
+ for (Iterator<DocumentType> i=types.iterator(); i.hasNext();) {
+ Hibernate.initialize(i.next()); // Supposed fetching document types
+ }
+ return types;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<DocumentType> selectResultTypes () {
+// -----------------------------------------------------
+ String query = "from DocumentType where result is not null order by result asc";
+
+ return Database.getSession().createQuery(query).list();
+ }
+
+ public static DocumentType selectType (String name) {
+// ---------------------------------------------------
+ String query = new StringBuffer("from DocumentType where name='").append(name).append("'").toString();
+
+ return (DocumentType)Database.getSession().createQuery(query).uniqueResult();
+ }
+
+ public static DocumentType selectType (int index) {
+// -------------------------------------------------
+ String query = new StringBuffer("from DocumentType where rid='").append(index).append("'").toString();
+
+ return (DocumentType)Database.getSession().createQuery(query).uniqueResult();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<DocumentType> selectTypesOf (ProjectSettings.Step step) {
+// --------------------------------------------------------------------------
+ Integer number = step.getNumber();
+ String query = new StringBuffer("from DocumentType").append(" where step like '%-").append(number).append("-%'").toString();
+
+ List<DocumentType> types = Database.getSession().createQuery(query).list();
+ for (Iterator<DocumentType> i=types.iterator(); i.hasNext();) {
+ Hibernate.initialize(i.next()); // For fetching document types
+ }
+ return types;
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected ConvertsRelation attach (String format) {
+// -------------------------------------------------
+ return attach(format, null);
+ }
+
+ protected ConvertsRelation attach (String format, String description) {
+// ---------------------------------------------------------------------
+ String path = this.getRelativePath();
+ File export = new File(path + "." + format);
+ ConvertsRelation attach = new ConvertsRelation(this, export, description);
+ Session session = Database.getSession();
+
+ session.save(export);
+ session.save(attach);
+
+ this.addRelation(attach); // Updates this
+
+ return attach;
+ }
+
+ protected boolean buildReferenceFrom (ProjectElement scope, Document lineage) {
+// -----------------------------------------------------------------------------
+ if (state != ProgressState.inWORK) return false;
+ Study owner = null;
+ Scenario context = null;
+ if (scope instanceof Study) owner = (Study)scope;
+ else {
+ context = ((Scenario)scope);
+ owner = context.getOwnerStudy();
+ }
+ did = lineage.did;
+ if (context != null && (lineage.isVersioned() || owner.shares(lineage))) {
+ version = new Revision(version).setBranch(context.getReference()).toString();
+ }
+ return true;
+ }
+
+ protected boolean buildReferenceFrom (Study scope) {
+// --------------------------------------------------
+ if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
+ DecimalFormat tostring = new DecimalFormat(suformat);
+
+ did = did.replace ("%" + suformat, tostring.format(scope.getLastLocalIndex()));
+ return true;
+ }
+
+ protected boolean demote () {
+// ---------------------------
+ ValidationStep torem;
+
+ if (state == ProgressState.inCHECK) {
+ state = ProgressState.inDRAFT;
+ torem = ValidationStep.REVIEW;
+// This operation must not change the version number of documents.
+// Consequently, inDRAFT documents may have a minor version number equal to zero.
+ } else
+ if (state == ProgressState.inDRAFT) {
+ state = ProgressState.inWORK;
+ torem = ValidationStep.PROMOTION;
+ } else {
+ return false;
+ }
+ for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
+ Relation link = i.next();
+ if (!(link instanceof StampRelation)) continue;
+ if (((StampRelation)link).getStampType() != torem) continue;
+ i.remove();
+ break;
+ }
+ Database.getSession().update(this);
+ return true;
+ }
+
+/**
+ * Increments the reference count of this document following its publication into a Study step.
+ *
+ * @see #release()
+ */
+ protected void hold () {
+// ----------------------
+ countag += 1;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+
+/**
+ * Defines this document.
+ *
+ * @param dprop the properties of the document
+ *
+ * @see Step#createDocument(Properties)
+ * @see #isUndefined()
+ */
+ protected void initialize (Properties dprop) throws MissedPropertyException, InvalidPropertyException, NotApplicableException {
+// --------------------------------------------
+ if (!this.isUndefined()) throw new NotApplicableException("Cannot initialize an existing Document");
+ if (dprop.name == null) throw new MissedPropertyException("name");
+ if (dprop.name.length() == 0) throw new InvalidPropertyException("name");
+ if (dprop.owner == null) throw new MissedPropertyException("owner");
+// if (dprop.owner instanceof Study && !ProjectSettings.getStep(step).appliesTo(Study.class)) {
+// throw new InvalidPropertyException("step");
+// }
+ name = dprop.name;
+ myfile.changePath( myfile.getRelativePath().replace("%n", getEncodedRootName((Study)dprop.owner)) );
+ if (history == -1) history = 0;
+ if (dprop.date == null) {
+ Calendar current = Calendar.getInstance();
+ lasdate = current.getTime(); // Today
+ } else {
+ lasdate = dprop.date;
+ }
+ Database.getSession().update(this);
+ }
+
+ protected boolean promote (Timestamp stamp) {
+// -------------------------------------------
+ ProgressState newstate = null;
+
+ if (state == ProgressState.inWORK) {
+ newstate = ProgressState.inDRAFT; // Promotion to being reviewed
+ } else
+ if (state == ProgressState.inDRAFT) {
+ newstate = ProgressState.inCHECK; // Promotion to approval
+ Revision myvers = new Revision(version);
+ if (myvers.isMinor()) {
+ version = myvers.incrementAs(newstate).toString();
+//TODO: If my physical file is programatically editable, update its (property) version number
+//ISSUE: What about attached files such as PDF if exist, should we remove them ?
+ }
+ } else
+ if (state == ProgressState.inCHECK) {
+ newstate = ProgressState.APPROVED;
+ }
+ this.state = newstate;
+ if (stamp != null) this.addRelation( stamp.getContext() );
+ Database.getSession().update(this);
+ return true;
+ }
+
+/**
+ * Decrements the reference count of this document following the removal of a Publication from a Study step.
+ *
+ * @see #hold()
+ */
+ protected void release () {
+// -------------------------
+ countag -= 1;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+
+ protected void rename (String title) throws InvalidPropertyException {
+// ------------------------------------
+ if (title.length() == 0) throw new InvalidPropertyException("name");
+
+ Calendar current = Calendar.getInstance();
+ this.name = title;
+ this.lasdate = current.getTime(); // Today
+ Database.getSession().update(this);
+ }
+
+ protected void updateAs (Revision newvers) {
+// ------------------------------------------
+ version = newvers.setBranch(version).toString(); // Branch names are propagated by the versionning
+ ProgressState newstate = ProgressState.inCHECK;
+ if (newvers.isMinor()) newstate = ProgressState.inWORK;
+ state = null; // Just to tell updateAs(sate) to not increment the version number
+ updateAs(newstate);
+ }
+
+ protected void updateAs (ProgressState state) {
+// ---------------------------------------------
+ Document previous = null;
+
+// Set of version number
+ if (state == ProgressState.EXTERN) {
+ if (this.state != ProgressState.EXTERN) this.version = null; // Strange use-case...
+ } else {
+ Revision myvers = new Revision(version);
+ if (!myvers.isNull()) { // Versionning context
+ for (Iterator<Relation> i=getAllRelations().iterator(); i.hasNext();) {
+ Relation link = i.next();
+ if (!link.getClass().equals(VersionsRelation.class)) continue;
+ previous = (Document)link.getTo(); // Versioned document
+ break;
+ }
+ }
+ if (this.state != null) myvers.incrementAs(state); // Incrementation if the reversion number is not imposed
+ this.version = myvers.toString();
+ }
+// Update this document and the previous version, if exit
+ Session session = Database.getSession();
+ if (previous != null) {
+ previous.history += 1;
+ session.update(previous);
+ }
+ this.state = state;
+ session.update(this);
+ }
+
+// protected void upgrade () {
+// -------------------------
+// if (this.state != ProgressState.inWORK) return;
+//
+// Calendar current = Calendar.getInstance();
+// for (Iterator<Relation> i=getAllRelations().iterator(); i.hasNext();) {
+// Relation link = i.next();
+// if (!link.getClass().equals(UsesRelation.class)) continue;
+//
+// Document used = (Document)link.getTo();
+// if (!used.isVersioned()) continue;
+//TODO: Update the uses relation
+// }
+// this.promote();
+// this.lasdate = current.getTime(); // Today
+// Database.getSession().update(this);
+//
+//TODO: Promote documents using this one
+// }
+
+// ==============================================================================================================================
+// Private services
+// ==============================================================================================================================
+
+ private String generateEncodedName (Study scope) {
+// ------------------------------------------------
+ StringBuffer encoding = new StringBuffer();
+ FileNaming scheme = ProjectSettings.getFileNamingScheme();
+ DecimalFormat tostring = new DecimalFormat(suformat);
+
+ int number = scope.generateLocalIndex();
+
+ if (scheme == FileNaming.encoded) {
+ encoding.append(scope.getReference()).append(".").append(tostring.format(number));
+ } else { // title and (temporarily) asis
+ encoding.append(name).append(".").append(tostring.format(number));
+ }
+ return encoding.toString();
+ }
+
+ private String getEncodedRootName (Study scope) {
+// -----------------------------------------------
+ FileNaming scheme = ProjectSettings.getFileNamingScheme();
+
+ if (scheme == FileNaming.encoded) return scope.getReference();
+ else return name;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class providing services for checking the rights related to operations on a given document.
+ * These rights are partially driven by the validation cycle associated to documents.
+ *
+ * @see ValidationCycle
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+//TODO: Review this rights in the following contexts:
+// - Document shared by several scenarios
+// - Document out-dated following a modification of a document it uses
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.splat.kernel.Relation;
+import org.splat.kernel.User;
+
+
+public class DocumentRights {
+
+ private User user;
+ private Publication operand;
+ private ValidationCycle cycle;
+ private boolean isauthor; // True if the user is author of the document
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+ public DocumentRights (User user, Publication tag) {
+// --------------------------------------------------
+ this.user = user;
+ this.operand = tag;
+ this.cycle = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
+ this.isauthor = operand.value().getAuthor().equals(user);
+//TODO: all contributors of the given document (when supported) must also behave as author
+ }
+ protected DocumentRights (Publication tag) {
+// ------------------------------------------
+ this.user = operand.value().getAuthor();
+ this.operand = tag;
+ this.cycle = operand.getOwnerStudy().getValidationCycleOf(operand.value().getType());
+ this.isauthor = true; // In order to ignore the author state in the context of any user
+//TODO: all contributors of the given document (when supported) must also behave as author
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+/**
+ * Checks if the user has right to accept the modifications of documents depending on the selected document.
+ * This operation applies to out-dated documents following a modification of documents they use.
+ * Only the author of the document has such right.
+ *
+ * @return true if the user has right to accept the modifications of dependencies of the document.
+ * @see Publication#accept()
+ */
+ public boolean canAccept () {
+// ---------------------------
+ if (!isauthor) return false;
+ return operand.isOutdated();
+ }
+
+/**
+ * Checks if the user has right to approve the selected document.
+ * Only the approver of the type of selected document has such right, providing that the document is candidate for approval and
+ * all document dependencies have already been approved.
+ *
+ * @return true if the user has right to approve the document.
+ * @see Publication#approve()
+ * @see ValidationCycle
+ */
+ public boolean canApprove () {
+// ----------------------------
+ User approver = cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
+
+ if (!user.equals(approver)) return false;
+ if (operand.getProgressState() != ProgressState.inCHECK) return false;
+
+ List<Relation> use = operand.value().getRelations(UsesRelation.class);
+ for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
+ Document depend = (Document)i.next().getTo();
+ ProgressState state = depend.getProgressState();
+ if (state == ProgressState.EXTERN) continue; // External documents do not follow this progress state
+ if (state != ProgressState.APPROVED) return false;
+ }
+ return true;
+ }
+
+/**
+ * Checks if the user has right to attach a file to the selected document.
+ * Both, the author, during the elaboration of the document, and the reviewer of the document, during the review process,
+ * have such right.
+ *
+ * @return true if the user has right to attach a file to the document.
+ * @see Publication#attach(String)
+ * @see Publication#attach(String, String)
+ */
+ public boolean canAttach () {
+// ---------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
+ ProgressState state = operand.value().getProgressState();
+
+ if (state == ProgressState.inWORK) return (isauthor);
+ else return (isauthor || user.equals(manager) || user.equals(reviewer));
+ }
+
+/**
+ * Checks if the user has right to demote the selected document.
+ * A document can be demoted providing that it is In-Draft or In-Check and all documents using it have previously been demoted.
+ * In-Draft documents can be demoted by default by both, the author of the document and the responsible of study, while
+ * documents in approval process can be demoted by their approver only.
+ *
+ * @return true if the user has right to demote the document.
+ * @see #canInvalidate()
+ * @see #canPromote()
+ * @see Publication#demote()
+ * @see ValidationCycle
+ */
+ public boolean canDemote () {
+// ---------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ User publisher = cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
+ User approver = cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
+ ProgressState mystate = operand.value().getProgressState();
+
+ if (mystate == ProgressState.inDRAFT) {
+ if (publisher == null) { if (!isauthor && !user.equals(manager)) return false;
+ } else if (!user.equals(publisher)) return false;
+ } else
+ if (mystate == ProgressState.inCHECK) {
+ if (!user.equals(approver)) return false;
+ } else return false;
+
+ List<Relation> use = operand.value().getRelations(UsedByRelation.class);
+ for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
+ Document depend = (Document)i.next().getTo();
+ ProgressState state = depend.getProgressState();
+ if (mystate == ProgressState.inDRAFT && state != ProgressState.inWORK) return false;
+ if (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) return false;
+ }
+ return true;
+ }
+
+/**
+ * Checks if the user has right to check-out the selected document for editing.
+ * In-Work documents can be checked-out by both, the author of the document and the responsible of study, while
+ * documents In-Draft can be checked-out by the reviewer only.
+ *
+ * @return true if the user has right to edit the document.
+ */
+ public boolean canEdit () {
+// -------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
+ ProgressState state = operand.value().getProgressState();
+
+//TODO: Should be restricted by the application if no editor available
+ if (state == ProgressState.inWORK) {
+ if (isauthor || user.equals(manager)) return true;
+ } else
+ if (state == ProgressState.inDRAFT) {
+ if (user.equals(reviewer)) return true;
+ }
+ return false;
+ }
+
+/**
+ * Checks if the user has right to promote the selected document.
+ * A document can be promoted providing that it is In-Work and all its dependencies have previously been promoted.
+ * By default, both the author of the document and the responsible of study has right to promote such document. Otherwise,
+ * only the user involved in the Promotion step of validation cycle of the selected document has such right.
+ *
+ * @return true if the user has right to promote the document.
+ * @see #canDemote()
+ * @see Publication#promote()
+ * @see ValidationCycle
+ */
+ public boolean canPromote () {
+// ----------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ User publisher = cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
+
+ if (operand.getProgressState() != ProgressState.inWORK) return false;
+ if (publisher == null) { if (!isauthor && !user.equals(manager)) return false;
+ } else { if (!user.equals(publisher)) return false;
+ }
+ List<Relation> use = operand.value().getRelations(UsesRelation.class);
+ for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
+ Document depend = (Document)i.next().getTo();
+ ProgressState state = depend.getProgressState();
+ if (state == ProgressState.EXTERN) continue; // External documents do not follow this progress state
+ if (state == ProgressState.inWORK) return false;
+ }
+ return true;
+ }
+
+/**
+ * Checks if the user has right to remove the history of the selected document, if exists.
+ * Only the responsible of the study have such right.
+ *
+ * @return true if the user has right to purge the document.
+ */
+ public boolean canPurge () {
+// --------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ Document doc = operand.value();
+
+ if (!user.equals(manager)) return false;
+ if (doc.isShared()) return false;
+ if (doc.getFirstRelation(VersionsRelation.class) == null) return false;
+ return true;
+ }
+
+/**
+ * Checks if the user has right to remove the selected document from the study.
+ * Both, the author of the document and the responsible of the study, have such right, providing that:
+ * - the document is neither in review or in approval process
+ * - the document is not used by any other document
+ *
+ * @return true if the user has right to remove the document.
+ * @see Step#removeDocument(Publication)
+ */
+ public boolean canRemove () {
+// ---------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ ProgressState state = operand.getProgressState();
+
+ if (!isauthor && !user.equals(manager)) return false;
+ if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
+
+ List<Publication> using = operand.getRelations(UsedByRelation.class);
+ return (using.size() == 0);
+ }
+
+/**
+ * Checks if the user has right to rename the selected document.
+ * Only the author of the document has such right, providing that the document is neither in review nor in approval process.
+ *
+ * @return true if the user has right to rename the document.
+ * @see Publication#rename(String)
+ */
+ public boolean canRename () {
+// ---------------------------
+ ProgressState state = operand.getProgressState();
+
+ if (!isauthor) return false; // In case of external document, the author is the one who has imported the document.
+ if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
+ return (!operand.value().isShared());
+ }
+
+/**
+ * Checks if the user has right to replace the source file of the selected document.
+ * Both, the author of the document and the responsible of study has such right, providing that the document is neither in review
+ * nor in approval process.
+ *
+ * @return true if the user has right to replace the document.
+ */
+ public boolean canReplace () {
+// ----------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ ProgressState state = operand.getProgressState();
+
+ if (!isauthor && !user.equals(manager)) return false; // Supposed to work also in case of external document.
+ if (state != ProgressState.inWORK && state != ProgressState.EXTERN) return false;
+ return !operand.value().isShared();
+ }
+
+/**
+ * Checks if the user has right to validate the selected document.
+ * Only the reviewer of the type of selected document has such right, providing that the document is being reviewed and
+ * all document dependencies have already been validated.
+ *
+ * @return true if the user has right to validate the document
+ * @see #canUnvalidate()
+ * @see Publication#review()
+ * @see ValidationCycle
+ */
+ public boolean canReview () {
+// ---------------------------
+ User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
+
+ if (!user.equals(reviewer)) return false;
+ if (operand.getProgressState() != ProgressState.inDRAFT) return false;
+
+ List<Relation> use = operand.value().getRelations(UsesRelation.class);
+ for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
+ Document depend = (Document)i.next().getTo();
+ ProgressState state = depend.getProgressState();
+ if (state == ProgressState.EXTERN) continue; // External documents do not follow this progress state
+ if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) return false;
+ }
+ return true;
+ }
+
+/**
+ * Checks if the user has right to undo the validation operation of the selected document.
+ * Both, the author and the reviewer of a validated document, have such right.
+ *
+ * @return true if the user has right to undo the validation operation
+ * @see #canDemote()
+ * @see #canReview()
+ * @see Publication#invalidate()
+ * @see ValidationCycle
+ */
+ public boolean canInvalidate () {
+// -------------------------------
+ User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
+ ProgressState mystate = operand.value().getProgressState();
+
+ if (mystate != ProgressState.inCHECK) return false;
+ if (!isauthor && !user.equals(reviewer)) return false;
+
+ List<Relation> use = operand.value().getRelations(UsedByRelation.class);
+ for (Iterator<Relation> i=use.iterator(); i.hasNext();) {
+ Document depend = (Document)i.next().getTo();
+ ProgressState state = depend.getProgressState();
+ if (mystate == ProgressState.inDRAFT && state != ProgressState.inWORK) return false;
+ if (mystate == ProgressState.inCHECK && (state != ProgressState.inDRAFT && state != ProgressState.inWORK)) return false;
+ }
+ return true;
+ }
+
+/**
+ * Checks if the user has right to version the selected document.
+ * In-Work documents can be versioned by both, the author of the document and the responsible of study, while
+ * documents In-Draft can be versioned by the reviewer only.
+ * Additionally, Approved documents can also be versioned by their author in order to enter in a new modification validation cycle.
+ *
+ * @return true if the user has right to version the document.
+ * @see Step#versionDocument(Publication)
+ * @see Step#versionDocument(Publication, Document.Properties)
+ * @see Step#versionDocument(Publication, String)
+ */
+ public boolean canVersion () {
+// ----------------------------
+ User manager = operand.getOwnerStudy().getAuthor();
+ User reviewer = cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
+ ProgressState state = operand.value().getProgressState();
+
+ if (state == ProgressState.inWORK) {
+ if (isauthor || user.equals(manager)) return true;
+ } else
+ if (state == ProgressState.inDRAFT) {
+ if (user.equals(reviewer)) return true;
+ } else
+ if (state == ProgressState.APPROVED) {
+ if (isauthor) return true;
+ }
+ return false;
+ }
+
+// ==============================================================================================================================
+// Getter
+// ==============================================================================================================================
+
+/**
+ * Returns the document subject of checks according to this user rights.
+ *
+ * @return the document subject of checks.
+ */
+ public Document getOperand () {
+// -----------------------------
+ return operand.value();
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.Persistent;
+
+
+public class DocumentType extends Persistent {
+
+// Persistent fields
+ private String name;
+ private ProgressState state;
+ private String step; // List of (dash separated) steps (numbers) containing this type
+ private String result; // Step (number ) having this type as result
+ private Set<DocumentType> uses;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private String name = null;
+ private String step = null;
+ private String result = null;
+ private DocumentType[] uses = null;
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ name = null;
+ step = null;
+ result = null;
+ uses = null;
+ }
+// - Setters of DocumentType properties
+
+ public Properties setName (String name) throws InvalidPropertyException
+ {
+ if (name.length() == 0) throw new InvalidPropertyException("name");
+ this.name = name;
+ return this;
+ }
+ public Properties setResult (ProjectSettings.Step step)
+ {
+ this.result = String.valueOf(step.getNumber());
+ return this;
+ }
+ public Properties setStep (ProjectSettings.Step... step)
+ {
+ this.step = "-";
+ for (int i=0; i<step.length; i++) this.step = this.step + String.valueOf(step[i].getNumber()) + "-";
+ return this;
+ }
+ public Properties setUses (DocumentType... type)
+ {
+ this.uses = type;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (name == null) throw new MissedPropertyException("name");
+ if (step == null) throw new MissedPropertyException("path");
+ }
+ }
+// Database fetch constructor
+ protected DocumentType () {
+// -------------------------
+ }
+// Initialization constructor
+ protected DocumentType (Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// -----------------------------------------
+ super(dprop); // Throws one of the above exception if not valid
+ name = dprop.name;
+ state = ProgressState.inCHECK;
+ step = dprop.step;
+ result = dprop.result; // May be null
+ uses = new HashSet<DocumentType>();
+ if (dprop.uses != null) for (int i=0; i<dprop.uses.length; i++) uses.add(dprop.uses[i]);
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean approve () {
+// -------------------------
+ if (state != ProgressState.inCHECK) return false;
+ this.state = ProgressState.APPROVED; // The type name is supposed being localized
+ Database.getSession().update(this);
+ return true;
+ }
+
+ public boolean equals(Object entity) {
+// ------------------------------------
+ if (entity == null) return false;
+ if (entity instanceof String) {
+ return this.name.equals((String)entity); // Names are unique
+ } else
+ if (entity instanceof DocumentType) {
+ DocumentType object = (DocumentType)entity;
+ int he = object.getIndex();
+ int me = this.getIndex();
+ if (me*he != 0) return (he == me);
+ else return this.getName().equals(object.getName());
+ } else {
+ return false;
+ }
+ }
+
+ public String getName () {
+// ------------------------
+ return name;
+ }
+
+ public Set<DocumentType> getDefaultUses () {
+// -------------------------------------------
+ return uses;
+ }
+
+ public boolean isApproved () {
+// ----------------------------
+ return (state == ProgressState.APPROVED);
+ }
+
+/**
+ * Checks if documents of this type are attached to the given study step, either as result or content.
+ *
+ * @param step the involved study step
+ * @return true if documents of this type are attached to the given step.
+ * @see #isResultOf(org.splat.som.ProjectSettings.Step)
+ */
+ public boolean isContentInto (ProjectSettings.Step step) {
+// --------------------------------------------------------
+ String[] path = this.step.split("-");
+ for (int i=0; i<path.length; i++) {
+ String value = path[i];
+ if (value.length() == 0) continue;
+ if (Integer.valueOf(value) == step.getNumber()) return true;
+ }
+ return false;
+ }
+
+/**
+ * Checks if documents of this type are result of any study step.
+ *
+ * @return true if documents of this type are result of a step.
+ * @see #isStudyResult()
+ * @see #isResultOf(org.splat.som.ProjectSettings.Step)
+ */
+ public boolean isStepResult () {
+// ------------------------------
+ return (result != null);
+ }
+
+/**
+ * Checks if documents of this type are result of a study.
+ * A document is the result of a study when it is the result of the last step of the study.
+ *
+ * @return true if documents of this type are result of a study.
+ * @see #isStepResult()
+ * @see #isResultOf(org.splat.som.ProjectSettings.Step)
+ */
+ public boolean isStudyResult () {
+// -------------------------------
+ List<ProjectSettings.Step> step = ProjectSettings.getAllSteps();
+ ProjectSettings.Step lastep = step.get( step.size()-1 );
+ return (this.isResultOf(lastep));
+ }
+
+/**
+ * Checks if documents of this type are result of the given study step.
+ *
+ * @param step the involved study step
+ * @return true if documents of this type are result of the given step.
+ * @see #isContentInto(org.splat.som.ProjectSettings.Step)
+ * @see #isStepResult()
+ * @see #isStudyResult()
+ */
+ public boolean isResultOf (ProjectSettings.Step step) {
+// -----------------------------------------------------
+ if (result == null) return false;
+ return (Integer.valueOf(result) == step.getNumber());
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class whose only purpose is to represent the kernel's Entity class for propagating to this package the visibility of relations
+ * and attributes editing functions.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Set;
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+import org.splat.kernel.ObjectProperties;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+
+
+public abstract class Entity extends org.splat.kernel.Entity {
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected Entity () {
+ }
+// Initialization constructor
+ protected Entity (ObjectProperties prop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// ----------------------------------------
+ super(prop);
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected Relation addRelation (Relation link) {
+// ----------------------------------------------
+ return super.addRelation(link);
+ }
+
+ protected Set<Relation> getAllRelations () {
+// ------------------------------------------
+ return super.getAllRelations();
+ }
+
+ protected void removeRelation (Class<? extends Relation> type, Persistent to) {
+// -----------------------------------------------------------------------------
+ super.removeRelation(type, to);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.File" table="file" lazy="false">
+
+<!-- Properties inherited Persistent
+ -->
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+<!-- File properties
+ -->
+ <!-- String format -->
+ <property name="format" column="format" access="field" not-null="true" />
+
+ <!-- String path -->
+ <property name="path" column="path" access="field" not-null="true" />
+
+ <!-- String date -->
+ <property name="date" column="date" access="field" not-null="true" />
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class of meta files representing physical files under the control of Study Manager.
+ * Typically, the files represented by this class are source files of Documents and exports in different formats.
+ * The path of such files is relative to the vault of the repository of Study Manager.
+ * When creating a Document, as the source file is produced by the caller which creates the Document, the corresponding
+ * physical file may not exist at instantiation time.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+
+import org.splat.kernel.Persistent;
+
+
+public class File extends Persistent {
+
+// Persistent fields
+ protected String format;
+ protected String path;
+ protected Date date;
+
+// Transient fields
+ private java.io.File myfile; // For optimization
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected File () {
+// -----------------
+ this.myfile = null;
+ }
+// Internal constructors
+ protected File (String path) {
+// ----------------------------
+ Calendar current = Calendar.getInstance();
+ String[] table = path.split("\\x2E");
+
+ this.format = table[table.length-1];
+ this.path = path; // The corresponding physical file may not exist yet
+ this.date = current.getTime(); // Today
+ this.myfile = null;
+ }
+ protected File (String path, String format, Date date) {
+// ------------------------------------------------------
+ this.path = path; // The corresponding physical file may not exist yet
+ this.format = format; // The format name may be different from the physical file extension
+ this.date = date;
+ if (date == null) {
+ Calendar current = Calendar.getInstance();
+ this.date = current.getTime(); // Today
+ }
+ this.myfile = null;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+/**
+ * Returns the data file associated to this meta file.
+ *
+ * @return the associated data file. If this meta data is an empty document, the returned file does not exist.
+ */
+ public java.io.File asFile () {
+// -----------------------------
+ if (myfile == null) myfile = new java.io.File(Database.getRepositoryVaultPath() + path);
+ return myfile;
+ }
+
+ public Date getDate () {
+// ----------------------
+ return date;
+ }
+
+ public String getFormat () {
+// --------------------------
+ return format;
+ }
+
+ public String getName () {
+// ------------------------
+ return this.asFile().getName();
+ }
+
+ public String getRelativePath () {
+// --------------------------------
+ return path;
+ }
+
+ public boolean exists () { // Shortcut
+// ------------------------
+ return (this.asFile().exists());
+ }
+
+// ==============================================================================================================================
+// Protected service
+// ==============================================================================================================================
+
+ protected void changePath (String path) {
+// ---------------------------------------
+ this.path = path;
+ this.myfile = null;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.IDBuilder" table="refid">
+
+ <!-- Integer cycle -->
+ <id name="cycle" column="cycle" access="field">
+ <generator class="assigned"/>
+ </id>
+
+ <!-- Integer base -->
+ <property name="base" column="base" access="field" />
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+public class IDBuilder {
+
+ @SuppressWarnings("unused")
+ private int cycle;
+ private int base; // Number of studies created in this cycle
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+ protected IDBuilder () {
+ }
+ protected IDBuilder (Date date) {
+// -------------------------------
+ SimpleDateFormat get = new SimpleDateFormat("yyyy");
+ String year = get.format(date);
+ cycle = Integer.valueOf(year);
+ base = 0;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ protected String buildReference (String pattern, Study study) {
+// -------------------------------------------------------------
+ char[] format = pattern.toCharArray();
+ char[] ref = new char[80]; // Better evaluate the length of the generated string
+ int next = base + 1;
+
+ int count = 0;
+ for (int i=0; i<format.length; i++) {
+
+// Insertion of attribute values
+ if (format[i] == '%') {
+ i += 1;
+
+ if (format[i] == 'y') { // Insertion of year in format 2 (e.g. 09) or 4 (e.g. 2009) digits
+ int n = i;
+ while (format[i] == 'y') {
+ i += 1;
+ if (i == format.length) break;
+ }
+ SimpleDateFormat tostring = new SimpleDateFormat("yyyy");
+ String year = tostring.format(study.getDate());
+ year = year.substring(4-(i-n), 4); // 4-(i-n) must be equal to either 0 or 2
+ for (int j=0; j<year.length(); j++) {
+ ref[count] = year.charAt(j);
+ count += 1;
+ }
+ i -= 1; // Back to the last 'y' character
+ } else
+ if (format[i] == '0') { // Insertion of the index
+ int n = i;
+ while (format[i] == '0') {
+ i += 1;
+ if (i == format.length) break;
+ }
+ DecimalFormat tostring = new DecimalFormat(pattern.substring(n, i));
+ String number = tostring.format(next);
+ for (int j=0; j<number.length(); j++) {
+ ref[count] = number.charAt(j);
+ count += 1;
+ }
+ i -= 1; // Back to the last '0' character
+ }
+// Keep the character
+ } else {
+ ref[count] = format[i];
+ count += 1;
+ }
+ }
+// Incrementation of the number of study
+ base = next;
+ Database.getSession().update(this);
+ return String.copyValueOf(ref, 0, count);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.LockObtainFailedException;
+import org.apache.lucene.util.Version;
+import org.splat.kernel.User;
+
+
+class Index {
+
+ private Directory index;
+ private org.apache.lucene.document.Document body;
+
+ protected static StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
+ private static final Logger logger = Logger.getLogger(Index.class);
+
+ private class Entry extends IndexWriter {
+// ---------------------------------------
+ private org.apache.lucene.document.Document entry;
+
+ private Entry (Study study) throws CorruptIndexException, LockObtainFailedException, IOException
+ {
+ super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
+
+// Addition of mandatory fields
+ entry = new org.apache.lucene.document.Document();
+ Field field;
+ field = body.getField("index");
+ field.setValue(String.valueOf(study.getIndex()));
+ entry.add(field);
+ field = body.getField("class");
+ field.setValue("Study");
+ entry.add(field);
+ field = body.getField("type");
+ field.setValue(""); // Reserved for configurable Study type
+ entry.add(field);
+ field = body.getField("ref");
+ field.setValue(study.getReference());
+ entry.add(field);
+ field = body.getField("area");
+ field.setValue(study.getVisibility().toString());
+ entry.add(field);
+ field = body.getField("state");
+ field.setValue(study.getProgressState().toString());
+ entry.add(field);
+ field = body.getField("author");
+ field.setValue(study.getAuthor().toString());
+ entry.add(field);
+ field = body.getField("title");
+ field.setValue(study.getTitle());
+ entry.add(field);
+ field = body.getField("contents");
+ field.setValue(study.getTitle());
+ entry.add(field);
+
+// Addition of optional fields
+ setActorsOf(study);
+ setContextAt(study.getSteps());
+ }
+ private Entry (KnowledgeElement kelm) throws CorruptIndexException, LockObtainFailedException, IOException
+ {
+ super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
+
+// Addition of mandatory fields
+ entry = new org.apache.lucene.document.Document();
+ Field field;
+ field = body.getField("index");
+ field.setValue(String.valueOf(kelm.getIndex()));
+ entry.add(field);
+ field = body.getField("class");
+ field.setValue("KnowledgeElement");
+ entry.add(field);
+ field = body.getField("type");
+ field.setValue(kelm.getType().getName());
+ entry.add(field);
+ field = body.getField("ref");
+ field.setValue(kelm.getReference());
+ entry.add(field);
+ field = body.getField("area");
+ field.setValue(kelm.getVisibility().toString());
+ entry.add(field);
+ field = body.getField("state");
+ field.setValue(kelm.getProgressState().toString());
+ entry.add(field);
+ field = body.getField("author");
+ field.setValue(kelm.getAuthor().toString());
+ entry.add(field);
+ field = body.getField("title");
+ field.setValue(kelm.getTitle());
+ entry.add(field);
+ field = body.getField("contents");
+ field.setValue(kelm.getTitle());
+ entry.add(field);
+
+//TODO: Addition of optional fields
+ Scenario scene = kelm.getOwnerScenario();
+ Study study = scene.getOwnerStudy();
+ setActorsOf(study); // For restricting the visibility of knowledges attached to private studies
+ setContextAt(study.getSteps());
+ setContextAt(scene.getSteps());
+ }
+ private void add () throws CorruptIndexException, IOException
+ {
+ addDocument(entry);
+// Save the new entry
+ optimize(); // Should be called before committing the index
+ close(); // Commits the index
+ }
+ private void update () throws CorruptIndexException, IOException
+ {
+ String value = entry.getField("ref").stringValue(); // Only field with unique value
+ Term term = new Term("ref").createTerm(value);
+ updateDocument(term, entry);
+// Save the updated entry
+ optimize(); // Should be called before committing the index
+ close(); // Commits the index
+ }
+ private void setContextAt (Step[] step)
+ {
+ for (int i=0; i<step.length; i++) {
+ List<SimulationContext> contexts = step[i].getAllSimulationContexts();
+ for (Iterator<SimulationContext> j=contexts.iterator(); j.hasNext();) {
+ SimulationContext context = j.next();
+ String type = String.valueOf(context.getType().getIndex());
+ String value = context.getValue();
+ entry.add( new Field(type, value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
+ }
+ }
+ }
+ private void setActorsOf (Study study)
+ {
+ Set<User> actors = study.getActors();
+ for (Iterator<User> i=actors.iterator(); i.hasNext(); ) {
+ String value = i.next().toString();
+ entry.add( new Field("actor", value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
+ }
+ }
+ }
+ public static class ObjectProxy implements Proxy, Serializable {
+// --------------------------------------------------------------
+ private int rid;
+ private String sid;
+ private ProgressState state;
+ private String title;
+ private String type;
+ private String name;
+ private static final long serialVersionUID = -4386494192709562221L;
+
+ public ObjectProxy (org.apache.lucene.document.Document ludoc) {
+ rid = Integer.valueOf(ludoc.get("index"));
+ sid = ludoc.get("ref");
+ state = ProgressState.valueOf(ludoc.get("state"));
+ title = ludoc.get("title");
+ name = ludoc.get("author");
+ }
+ public String getAuthorName () {
+ return name;
+ }
+ public Integer getIndex () {
+ return rid;
+ }
+ public ProgressState getProgressState () {
+ return state;
+ }
+ public String getReference () {
+ return sid;
+ }
+ public String getTitle () {
+ return title;
+ }
+ public String getType () {
+ return type;
+ }
+ }
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+ protected static void create () throws IOException {
+// -------------------------------
+ Directory index = FSDirectory.open(Database.getRepositoryIndexDirectory());
+ IndexWriter writer = new IndexWriter(index, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
+ writer.close(); // ==== Creates an empty index
+ }
+
+ protected Index () throws IOException {
+// ------------------
+ File indir = Database.getRepositoryIndexDirectory();
+ index = FSDirectory.open(indir);
+ body = new org.apache.lucene.document.Document();
+ body.add( new Field("index", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("class", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("type", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("ref", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("area", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("state", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("author", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("title", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
+ body.add( new Field("contents","", Field.Store.NO, Field.Index.ANALYZED) );
+ }
+
+// ==============================================================================================================================
+// Member functions
+// ==============================================================================================================================
+
+ protected void add (Study study) throws IOException {
+// --------------------------------
+ Index.Entry entry = new Entry(study);
+ entry.add();
+ if (logger.isInfoEnabled()) {
+ logger.info("Study \"" + study.getIndex() + "\" indexed.");
+ }
+ }
+
+ protected void add (KnowledgeElement kelm) throws IOException {
+// ------------------------------------------
+ Index.Entry entry = new Entry(kelm);
+ entry.add();
+ if (logger.isInfoEnabled()) {
+ logger.info("Knowledge \"" + kelm.getIndex() + "\" indexed.");
+ }
+ }
+
+ protected boolean exists () {
+// ---------------------------
+ try {
+ return IndexReader.indexExists(index);
+ }
+ catch (IOException error) {
+ error.printStackTrace();
+ return false;
+ }
+ }
+
+ protected void update (Study study) throws IOException {
+// -----------------------------------
+ Index.Entry entry = new Entry(study);
+ entry.update();
+ if (logger.isInfoEnabled()) {
+ logger.info("Study \"" + study.getIndex() + "\" re-indexed.");
+ }
+ }
+
+ protected void update (KnowledgeElement kelm) throws IOException {
+// ---------------------------------------------
+ Index.Entry entry = new Entry(kelm);
+ entry.update();
+ if (logger.isInfoEnabled()) {
+ logger.info("Knowledge \"" + kelm.getIndex() + "\" re-indexed.");
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.KnowledgeElement" table="knowelm" lazy="false">
+
+<!-- Properties inherited Persistent
+ -->
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+<!-- KnowledgeElement properties
+ -->
+ <!-- KnowledgeElementType type -->
+ <many-to-one name="type" column="type" access="field" not-null="true" />
+
+ <!-- String title -->
+ <property name="title" column="title" access="field" not-null="true" />
+
+ <!-- String value -->
+ <property name="value" type="text" column="value" access="field" not-null="true" />
+
+ <!-- Scenario owner -->
+ <many-to-one name="owner" column="owner" access="field" not-null="true" />
+
+ <!-- ProgressState state -->
+ <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
+
+ <!-- User author -->
+ <many-to-one name="author" column="author" access="field" not-null="true" />
+
+ <!-- Date date -->
+ <property name="date" column="date" access="field" not-null="true" />
+
+ </class>
+
+<!-- Class KnowledgeElementType
+ -->
+ <class name="org.splat.som.KnowledgeElementType" table="knowtype" lazy="false">
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+ <property name="name" column="name" access="field" not-null="true" />
+ <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.text.DecimalFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Vector;
+
+import org.hibernate.Session;
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.User;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+
+
+public class KnowledgeElement extends Persistent {
+
+ private KnowledgeElementType type; // User extendable types
+ private Scenario owner;
+ private ProgressState state;
+ private String title;
+ private String value;
+ private User author;
+ private Date date;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private String kid = null; // Search criterion only
+ private KnowledgeElementType type = null;
+ private Scenario owner = null;
+ private Visibility visibility = null; // Search criterion only
+ private ProgressState state = null;
+ private String title = null;
+ private String value = null;
+ private User author = null;
+ private User actor = null; // Search criterion only
+ private Date date = null;
+ private List<SimulationContext> context = new Vector<SimulationContext>(); // Search criterion only
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ kid = null;
+ type = null;
+ owner = null;
+ visibility = null;
+ state = null;
+ title = null;
+ value = null;
+ author = null;
+ actor = null;
+ date = null;
+ context = new Vector<SimulationContext>(); // as clear() may generate side effects
+ }
+ public Properties copy () {
+ Properties copy = new Properties();
+ copy.kid = this.kid;
+ copy.type = this.type;
+ copy.owner = this.owner;
+ copy.visibility = this.visibility;
+ copy.state = this.state;
+ copy.title = this.title;
+ copy.value = this.value;
+ copy.author = this.author;
+ copy.actor = this.actor;
+ copy.date = this.date;
+ copy.context = this.context;
+ return copy;
+ }
+// - Protected services
+
+ protected User getActor () {
+ return actor;
+ }
+ protected User getAuthor () {
+ return author;
+ }
+ protected ProgressState getProgressState () {
+ return state;
+ }
+ protected String getReference () {
+ return kid;
+ }
+ protected List<SimulationContext> getSimulationContexts () {
+ return context;
+ }
+ protected String getTitle () {
+ return title;
+ }
+ protected KnowledgeElementType getType () {
+ return type;
+ }
+ protected Visibility getVisibility () {
+ return visibility;
+ }
+// - Property setters
+
+// For building a search query
+ public Properties setActor (User actor)
+ {
+ this.actor = actor;
+ return this;
+ }
+ public Properties setAuthor (User user)
+ {
+ this.author = user;
+ return this;
+ }
+ public Properties setDate (Date date)
+ {
+ this.date = date;
+ return this;
+ }
+ protected Properties setOwnerScenario (Scenario owner)
+ {
+ this.owner = owner;
+ return this;
+ }
+// For building a search query
+ public Properties setReference (String kid) throws InvalidPropertyException
+ {
+ if (kid.length() == 0) throw new InvalidPropertyException("reference");
+ this.kid = kid;
+ return this;
+ }
+// For building a search query
+ public Properties setSimulationContexts (List<SimulationContext> context) {
+ this.context = context;
+ return this;
+ }
+ public Properties setState (ProgressState state) throws InvalidPropertyException
+ {
+ if (state != ProgressState.inWORK && state != ProgressState.inDRAFT && state != ProgressState.inCHECK && state != ProgressState.APPROVED) {
+ throw new InvalidPropertyException("state");
+ }
+ this.state = state;
+ return this;
+ }
+ public Properties setTitle (String title) throws InvalidPropertyException
+ {
+ if (title.length() == 0) throw new InvalidPropertyException("title");
+ this.title = title;
+ return this;
+ }
+ public Properties setType (KnowledgeElementType type)
+ {
+ this.type = type;
+ return this;
+ }
+ public Properties setValue (String value) throws InvalidPropertyException
+ {
+ if (value.length() == 0) throw new InvalidPropertyException("value");
+ this.value = value;
+ return this;
+ }
+// For building a search query
+ public Properties setVisibility (Visibility area)
+ {
+ this.visibility = area;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (type == null) throw new MissedPropertyException("type");
+ if (owner == null) throw new MissedPropertyException("owner");
+ if (title == null) throw new MissedPropertyException("title");
+ if (value == null) throw new MissedPropertyException("value");
+ if (author == null) throw new MissedPropertyException("author");
+ }
+ }
+// Database fetch constructor
+ protected KnowledgeElement () {
+ }
+// Internal constructor
+ protected KnowledgeElement (Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+ super(kprop); // Throws one of the above exception if not valid
+ type = kprop.type;
+ owner = kprop.owner;
+ title = kprop.title;
+ author = kprop.author;
+
+ date = kprop.date;
+ if (date == null) {
+ Calendar current = Calendar.getInstance();
+ date = current.getTime(); // Today
+ }
+ state = kprop.state;
+ if (state == null) {
+ if (type.isReserved()) state = ProgressState.inWORK;
+ else state = ProgressState.inDRAFT;
+ }
+ value = kprop.value.trim();
+ if (!value.startsWith("<p>")) {
+ StringBuffer text = new StringBuffer("<p>");
+ int index = value.indexOf("<p>");
+ if (index > 0) {
+ value = text.append(value.substring(0, index)).append("</p>").append(value.substring(index)).toString();
+ } else {
+ value = text.append(value).append("</p>").toString();
+ }
+ }
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean approve () {
+// -------------------------
+ if (state != ProgressState.inCHECK) return false;
+ state = ProgressState.APPROVED;
+ return updateMe();
+ }
+
+ public boolean demote () {
+// ------------------------
+ if (state != ProgressState.APPROVED && state != ProgressState.inCHECK) return false;
+ state = ProgressState.inDRAFT;
+ return updateMe();
+ }
+
+ public boolean equals (KnowledgeElement given) {
+// ----------------------------------------------
+ if (isSaved()) return (this.getIndex() == given.getIndex());
+ if (!this.getType().getName().equals(given.getType().getName())) return false;
+ if (this.getValue().equals(given.getValue())) return true;
+ return false;
+ }
+
+ public User getAuthor () {
+// ------------------------
+ return author;
+ }
+
+ public Date getDate () {
+// ----------------------
+ return date;
+ }
+
+ public Scenario getOwnerScenario () {
+// -----------------------------------
+ return owner;
+ }
+
+ public ProgressState getProgressState () {
+// ----------------------------------------
+ return state;
+ }
+
+ public String getTitle () {
+// -------------------------
+ return title;
+ }
+
+ public String getReference () {
+// -----------------------------
+ DecimalFormat toString = new DecimalFormat("00000"); // Supports 99 999 knowledge elements
+ return "KE" + toString.format(this.getIndex());
+ }
+
+ public KnowledgeElementType getType () {
+// --------------------------------------
+ return type;
+ }
+
+ public String getValue () {
+// -------------------------
+ return value;
+ }
+
+ public Visibility getVisibility () {
+// ----------------------------------
+ return getOwnerScenario().getOwnerStudy().getVisibility();
+ }
+
+ public boolean promote () {
+// -------------------------
+ if (state != ProgressState.inDRAFT) return false;
+ state = ProgressState.inCHECK;
+ return updateMe();
+ }
+
+ public void rename (String title) throws InvalidPropertyException {
+// ---------------------------------
+ if (title.length() == 0) throw new InvalidPropertyException("name");
+ this.title = title;
+ updateMe();
+ }
+
+ public void update (String description) {
+// ---------------------------------------
+ value = description.trim();
+ if (!value.startsWith("<p>")) {
+ StringBuffer text = new StringBuffer("<p>");
+ int index = value.indexOf("<p>");
+ if (index > 0) {
+ value = text.append(value.substring(0, index)).append("</p>").append(value.substring(index)).toString();
+ } else {
+ value = text.append(value).append("</p>").toString();
+ }
+ }
+ Database.getSession().update(this); // No need to update the Lucene index
+ }
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public static KnowledgeElementType createType (String name) throws RuntimeException {
+// -----------------------------------------------------------
+//TODO: Check for duplicate definition
+ KnowledgeElementType kelt = new KnowledgeElementType(name);
+ Session session = Database.getSession();
+ session.save(kelt);
+
+ return kelt;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<KnowledgeElementType> selectAllTypes () {
+// ----------------------------------------------------------
+ StringBuffer query = new StringBuffer("from KnowledgeElementType");
+ query = query.append(" order by rid asc");
+ return Database.getSession().createQuery(query.toString()).list();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<KnowledgeElementType> selectTypesWhere (ProgressState state) {
+// -------------------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from KnowledgeElementType where state='").append(state).append("'");
+ query = query.append(" order by rid asc");
+ return Database.getSession().createQuery(query.toString()).list();
+ }
+
+ public static KnowledgeElementType selectType (String name) {
+// -----------------------------------------------------------
+ StringBuffer query = new StringBuffer("from KnowledgeElementType where name='").append(name).append("'");
+ return (KnowledgeElementType)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static KnowledgeElementType selectType (int index) {
+// ---------------------------------------------------------
+ StringBuffer query = new StringBuffer("from KnowledgeElementType where rid='").append(index).append("'");
+ return (KnowledgeElementType)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected boolean updateMe () {
+// -----------------------------
+ try {
+ Database.getSession().update(this);
+ Database.getIndex().update(this);
+ return true;
+ }
+ catch (Exception error) {
+// logger.error("Unable to re-index the knowledge '" + getIndex() + "', reason:", error);
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+
+
+public class KnowledgeElementType extends Persistent {
+
+ private String name;
+ private ProgressState state;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected KnowledgeElementType () {
+ }
+// Initialization constructor
+ protected KnowledgeElementType (String name) {
+// --------------------------------------------
+ super();
+ this.name = name;
+ this.state = ProgressState.inCHECK;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean approve () {
+// -------------------------
+ if (state != ProgressState.inCHECK) return false;
+ this.state = ProgressState.APPROVED; // The type name is supposed being localized
+ if (this.isSaved()) Database.getSession().update(this);
+ return true;
+ }
+
+ public boolean equals(Object entity) {
+// ------------------------------------
+ if (entity == null) return false;
+ if (entity instanceof String) {
+ return this.name.equals((String)entity); // Names are unique
+ } else
+ if (entity instanceof KnowledgeElementType) {
+ KnowledgeElementType object = (KnowledgeElementType)entity;
+ int he = object.getIndex();
+ int me = this.getIndex();
+ if (me*he != 0) return (he == me);
+ else return this.getName().equals(object.getName());
+ } else {
+ return false;
+ }
+ }
+
+ public String getName () {
+// ------------------------
+ return name;
+ }
+
+ public boolean isApproved () {
+// ----------------------------
+ return (state == ProgressState.APPROVED);
+ }
+
+ public boolean isReserved () {
+// ----------------------------
+ return (state == ProgressState.inWORK);
+ }
+
+// ==============================================================================================================================
+// Protected service
+// ==============================================================================================================================
+/**
+ * Reserves this type for the management of simulation contexts.
+ * For being able to get the studies in which simulation contexts are used, all study scenarios are indexed through this
+ * knowledge element type, whether they include knowledge elements or not.
+ */
+ protected boolean reserve () {
+// ----------------------------
+ if (state != ProgressState.inCHECK) return false;
+ this.state = ProgressState.inWORK;
+ if (this.isSaved()) Database.getSession().update(this);
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public enum Profile {
+ studengineer, // Standard user working on simulation studies
+ manager, // User with study creation right
+ knowledgineer, // Knowledge Engineer in charge of the management of simulation contexts and knowledge elements
+ sysadmin, // System Administrator in charge of administration of the database
+ customer
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public enum ProgressState {
+ inPROGRESS, // Represents inWORK, inDRAFT and inCHECK states for search purpose
+ inWORK, inDRAFT, inCHECK, APPROVED,
+ EXTERN, // Document-specific state representing documents produced outside studies
+ TEMPLATE // Study-specific state qualifying typical reference studies
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of properties common to Study and Scenario
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.ProjectElement" abstract="true">
+
+<!-- Properties inherited from Entity
+ -->
+ <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
+ <generator class="org.splat.kernel.IDGenerator"/>
+ </id>
+ <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Attribute" />
+ </set>
+ <set name="relations" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Relation" />
+ </set>
+
+<!-- ProjectElement properties common to Study and Scenario
+ -->
+ <property name="title" column="title" access="field" not-null="true" />
+ <property name="credate" column="credate" access="field" not-null="true" />
+ <property name="lasdate" column="lasdate" access="field" not-null="true" />
+ <many-to-one name="manager" column="manager" access="field" not-null="true" />
+ <list name="contex" table="projext" lazy="false" access="field">
+ <key column="owner" />
+ <list-index column="ordex" />
+ <many-to-many column="rid" class="org.splat.som.SimulationContext" />
+ </list>
+ <set name="docums" inverse="true" lazy="false" order-by="`rid` desc" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.som.Publication" />
+ </set>
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.log4j.Logger;
+
+import org.splat.kernel.ObjectProperties;
+import org.splat.kernel.User;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+
+
+public abstract class ProjectElement extends Entity {
+
+// Persistent fields
+ protected String title;
+ protected User manager;
+ protected Date credate; // Object creation date
+ protected Date lasdate; // Object Last modification date
+ private List<SimulationContext> contex; // Structured by the Step transient class
+ private Set<Publication> docums; // Structured by the Step transient class
+
+// Transient field
+ private Step[] folders;
+
+ protected final static Logger logger = Logger.getLogger(ProjectElement.class);
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected ProjectElement () {
+// ---------------------------
+ folders = null;
+ }
+// Initialization constructor
+ protected ProjectElement (ObjectProperties oprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// -------------------------------------------------
+ super(oprop); // Throws one of the above exception if not valid
+ title = null; // Initialized by subclasses
+ credate = null; // Initialized by subclasses
+ lasdate = null; // Initialized by subclasses
+ docums = new LinkedHashSet<Publication>();
+ contex = new Vector<SimulationContext>();
+
+ folders = null;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public User getAuthor () {
+// ------------------------
+ return manager;
+ }
+
+/**
+ * Returns the creation date of this Project Element.
+ */
+ public Date getDate () {
+// ----------------------
+ return credate;
+ }
+
+ public String getDescription () {
+// -------------------------------
+ String summary = null;
+ DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
+ if (field != null) summary = field.getValue();
+ return summary; // May be null
+ }
+
+ public Step getFirstStep () {
+// ---------------------------
+ return this.getSteps()[0];
+ }
+
+ public Date getLastModificationDate () {
+// --------------------------------------
+ return lasdate;
+ }
+
+ public Step getLastStep () {
+// --------------------------
+ Step[] mystep = this.getSteps(); // For getting the folders length, if null
+ return mystep[mystep.length-1];
+ }
+
+/**
+ * Returns the publication into this Project Element of the given document version, if exists.
+ * If exists, a document publication id unique in a given ProjectElement.
+ *
+ * @param doc a document version published into this Project Element
+ * @return the publication of the document version, or null if the given document version is not published into this Project Element
+ */
+ public Publication getPublication (Document doc) {
+// ------------------------------------------------
+ int index = doc.getIndex();
+ for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
+ Publication found = i.next();
+ if (found.value().getIndex() == index) return found; // A document publication is unique in a given ProjectElement
+ }
+ return null;
+ }
+
+ public Step[] getSteps () {
+// -------------------------
+ if (folders == null) {
+ List<ProjectSettings.Step> steps = ProjectSettings.getStepsOf(this.getClass());
+ Iterator<ProjectSettings.Step> nstep = steps.iterator();
+
+ folders = new Step[steps.size()];
+ for (int i=0; i<folders.length; i++) {
+ folders[i] = new Step(nstep.next(), this);
+ }
+ }
+ return folders; // No protection against this object corruption as it would not corrupt the database
+ }
+
+ public String getTitle () {
+// -------------------------
+ return title;
+ }
+
+ public boolean publishes (Document doc) {
+// ---------------------------------------
+ int index = doc.getIndex();
+ for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
+ Document found = i.next().value();
+ if (found.getIndex() == index) return true;
+ }
+ return false;
+ }
+
+ public Iterator<Publication> PublicationIterator () {
+// ---------------------------------------------------
+ return Collections.unmodifiableSet(docums).iterator();
+ }
+
+ public Iterator<SimulationContext> SimulationContextIterator () {
+// ---------------------------------------------------------------
+ return Collections.unmodifiableList(contex).iterator();
+ }
+
+// ==============================================================================================================================
+// Protected member functions
+// ==============================================================================================================================
+
+ protected boolean add (Publication newdoc) {
+// ------------------------------------------
+ return docums.add(newdoc);
+ }
+
+ protected boolean add (SimulationContext newdoc) {
+// ------------------------------------------------
+ return contex.add(newdoc);
+ }
+
+ protected boolean remove (Publication oldoc) {
+// --------------------------------------------
+ return docums.remove(oldoc); // The removed tag becoming orphan, it is supposed automatically deleted from the data store
+ }
+
+ protected boolean remove (SimulationContext oldoc) {
+// --------------------------------------------------
+ return contex.remove(oldoc);
+ }
+
+/**
+ * Refreshes the internal data potentially out-of-date.
+ * This function needs to be called when Publication objects are added to this Project Element before being saved. The reason is,
+ * as saving a persistent object changes its hashcode, hashed data need to be rebuilt after saving for making functions based
+ * on this hashcode such as remove(), working.
+ */
+ protected void refresh () {
+// -------------------------
+ Publication[] curdoc = docums.toArray(new Publication[docums.size()]);
+
+ folders = null; // Just in case
+ docums.clear();
+ for (int i=0; i<curdoc.length; i++) docums.add(curdoc[i]);
+// No need to rebuild the list of SimulationContext as it does not use hashcodes
+ Database.getSession().update(this);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.splat.manox.XDOM;
+import org.splat.som.ValidationCycle.Actor;
+
+
+public class ProjectSettings {
+
+// Non persistent configuration information
+ private Properties reprop; // Repository settings
+ private String pattern; // Pattern of study references
+ private FileNaming naming; // Scheme of file names stored into the repository
+ private String versioning; // Pattern of the presentation of version numbers
+ private Vector<Step> steps; // Ordered list of (transient) study steps
+ private Vector<ValidationCycle> concycles; // Configuration document validation cycles
+
+// Temporary attributes initialized from the configuration file for populating the database with object types
+ private LinkedHashMap<String,String> mapuse; // Document type names and uses mapping
+ private Vector<String> context; // Simulation Context type names
+ private Vector<String> kname; // Knowledge Element type names
+ private Vector<NamedNodeMap> flows; // Document flows
+ private Vector<NamedNodeMap> sclass; // Study classifications
+
+// Other resources
+ private static ProjectSettings my = null; // Singleton instance
+ protected final static Logger logger = Logger.getLogger(ProjectSettings.class);
+
+ protected enum FileNaming { title, encoded, asis }
+ public static class Step {
+// ------------------------
+ private int number;
+ private Class<? extends ProjectElement> level; // Study or Scenario
+ private Set<Class<?>> contents; // Set of Document and/or Knowledge
+ private String path;
+
+ private Step (int number, Class<? extends ProjectElement> level, String path) {
+ this.initialize(number, level, path);
+ }
+ private Step (int number, Class<? extends ProjectElement> level, Class<?> contents, String path) {
+ this.initialize(number, level, path);
+ this.contents.add(contents);
+ }
+ private void initialize (int number, Class<? extends ProjectElement> level, String path) {
+ this.number = number;
+ this.level = level;
+ this.path = path + "/";
+ this.contents = new HashSet<Class<?>>();
+ }
+ public boolean appliesTo (Class<? extends ProjectElement> level) {
+ return (level == this.level);
+ }
+ public boolean mayContain (Class<?> type) {
+ return contents.contains(type);
+ }
+ public int getNumber () {
+ return number;
+ }
+ public String getPath () {
+ return path;
+ }
+ }
+ public static class ValidationCycle {
+// -----------------------------------
+ private String name;
+ private Actor[] actor;
+
+ private ValidationCycle () {
+ this.name = "built-in";
+ this.actor = new Actor[] { null, null, null };
+ }
+ private ValidationCycle (String name, Actor[] actor) {
+ this.name = name;
+ this.actor = actor;
+ }
+ public String getName () {
+ return name;
+ }
+ public Actor[] getActorTypes () {
+ return actor;
+ }
+ }
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+ public static ProjectSettings getMe () {
+// --------------------------------------
+ if (my == null) my = new ProjectSettings();
+ return my;
+ }
+ protected ProjectSettings () {
+// ----------------------------
+ reprop = new Properties();
+ steps = new Vector<Step>();
+ }
+
+// ==============================================================================================================================
+// Public functions
+// ==============================================================================================================================
+
+ public void configure (String filename) throws IOException, SQLException {
+// ---------------------------------------
+ if (!steps.isEmpty()) return; // Project already configured
+
+ Database base = Database.getMe();
+ File config = new File(filename);
+ if (config.exists()) {
+ loadCustomization(config);
+ } else {
+ logger.fatal("Could not find the database configuration file \"" + config.getAbsolutePath() + "\"");
+ throw new FileNotFoundException();
+ }
+ base.configure(reprop);
+ if (!base.isInitialized()) {
+ base.initialize();
+//TODO: Move the second part of loadCustomization here
+ }
+ }
+
+ public static List<Step> getAllSteps () {
+// ---------------------------------------
+ return my.steps;
+ }
+
+/**
+ * Return the validation cycles of result documents defined in the workflow, ordered by study activities
+ * and ending by the default validation cycle, if defined.
+ *
+ * @return the validation cycles of the workflow
+ */
+ public static List<ValidationCycle> getAllValidationCycles () {
+// -------------------------------------------------------------
+ return my.concycles;
+ }
+
+ public static FileNaming getFileNamingScheme () {
+// -----------------------------------------------
+ return my.naming;
+ }
+
+ public static ValidationCycle getNewValidationCycle () {
+// ------------------------------------------------------
+ return new ValidationCycle();
+ }
+
+ public static String getReferencePattern () {
+// -------------------------------------------
+ return my.pattern;
+ }
+
+ public static String getRevisionPattern () {
+// ------------------------------------------
+ return my.versioning;
+ }
+
+ public static Step getStep (int number) {
+// ---------------------------------------
+ for (int i=0; i<my.steps.size(); i++) {
+ Step step = my.steps.get(i);
+ if (step.number == number) return step;
+ }
+ return null;
+ }
+
+ public static List<Step> getStepsOf (Class<? extends ProjectElement> level) {
+// ---------------------------------------------------------------------------
+ Vector<Step> result = new Vector<Step>();
+
+ for (int i=0; i<my.steps.size(); i++) {
+ Step step = my.steps.get(i);
+ if (step.appliesTo(level)) result.add(step);
+ }
+ return result;
+ }
+
+// ==============================================================================================================================
+// Protected member function
+// ==============================================================================================================================
+
+ protected void initialize () {
+// ----------------------------
+ createDocumentTypes();
+ createSimulationContextTypes();
+ createKnowledgeElementTypes();
+ }
+
+// ==============================================================================================================================
+// Private member function
+// ==============================================================================================================================
+
+ private void loadCustomization (File config) {
+// --------------------------------------------
+ try {
+ DocumentBuilderFactory dfactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
+
+ org.w3c.dom.Document conf = dBuilder.parse(config.getPath());
+ HashMap<String, Node> children = XDOM.getNamedChildNodes(conf.getDocumentElement());
+
+// Repository tag initializing the reprop attribute
+ Node child = children.get("database");
+ HashMap<String, Node> datag = XDOM.getNamedChildNodes(child);
+
+ String disk = datag.get("repository").getAttributes().getNamedItem("disk").getNodeValue();
+ if (!disk.endsWith("/")) disk = disk + "/";
+ logger.info("Database root set to " + disk);
+ reprop.setProperty("repository", disk);
+
+// Formats tag initializing the reference pattern and date attributes
+ child = children.get("formats");
+ datag = XDOM.getNamedChildNodes(child);
+
+ NamedNodeMap natr = datag.get("references").getAttributes();
+ pattern = natr.getNamedItem("study").getNodeValue();
+
+ natr = datag.get("files").getAttributes();
+ naming = FileNaming.valueOf(natr.getNamedItem("name").getNodeValue());
+
+ natr = datag.get("versions").getAttributes();
+ versioning = natr.getNamedItem("pattern").getNodeValue();
+
+// Activities tag initializing the steps and rex attributes
+ child = children.get("activities");
+ NodeList nlist = child.getChildNodes();
+ Vector<NamedNodeMap> flist = new Vector<NamedNodeMap>();
+ Vector<String> resultype = new Vector<String>();
+ Vector<NamedNodeMap> clist = new Vector<NamedNodeMap>();
+
+ int snum = 1; // Base number of steps
+ for (int i=0; i<nlist.getLength(); i++) {
+ child = nlist.item(i);
+ if (child.getNodeName().equals("scenario")) {
+ NodeList slist = child.getChildNodes();
+ for (int j=0; j<slist.getLength(); j++) {
+ child = slist.item(j);
+ if (!child.getNodeName().equals("step")) continue;
+ HashMap<String, Node> tags = XDOM.getNamedChildNodes(child);
+
+ natr = tags.get("storage").getAttributes();
+ Step step = new Step(snum, Scenario.class, natr.getNamedItem("path").getNodeValue());
+
+// Keeping flow and classification information for eventual later use
+ natr = tags.get("flow").getAttributes();
+ flist.add(natr);
+ child = natr.getNamedItem("result");
+ if (child != null) resultype.add(child.getNodeValue());
+
+ child = tags.get("classification");
+ if (child != null) clist.add( child.getAttributes() );
+ else clist.add( null );
+
+ if (natr.getNamedItem("contents").getNodeValue().equals("knowledge")) {
+//TODO In a given scenario, only one step must contain knowledges
+ step.contents.add(KnowledgeElement.class);
+ } else {
+ step.contents.add(Document.class);
+ }
+ steps.add(step);
+ snum += 1;
+ }
+ } else {
+ if (!child.getNodeName().equals("step")) continue;
+ HashMap<String, Node> tags = XDOM.getNamedChildNodes(child);
+
+ natr = tags.get("storage").getAttributes(); // Mandatory information
+ Step step = new Step(snum, Study.class, natr.getNamedItem("path").getNodeValue());
+
+// Keeping flow and classification information for eventual later use
+ natr = tags.get("flow").getAttributes();
+ flist.add(natr);
+ child = natr.getNamedItem("result");
+ if (child != null) resultype.add(child.getNodeValue());
+
+ child = tags.get("classification"); // Optional information
+ if (child != null) clist.add( child.getAttributes() );
+ else clist.add( null );
+
+ if (natr.getNamedItem("contents").getNodeValue().equals("knowledge")) {
+//TODO Error: knowledges must be attached to scenarios
+ } else {
+ step.contents.add(Document.class);
+ }
+ steps.add(step);
+ snum += 1;
+ }
+ }
+// Validations tag
+ child = children.get("validations");
+ concycles = new Vector<ValidationCycle>();
+ datag = XDOM.getNamedChildNodes(child);
+
+ String[] step = { "review", "approval", "acceptance" };
+ resultype.add("default");
+ for (Iterator<String> i=resultype.iterator(); i.hasNext(); ) {
+ Actor[] actor = { null, null, null };
+ String name = i.next();
+ child = datag.get(name);
+ if (child == null) continue; // Document type not subject of any validation
+ natr = child.getAttributes();
+ for (int j=0; j<step.length; j++) {
+ child = natr.getNamedItem(step[j]);
+ if (child == null) continue; // Validation step not required
+ actor[j] = Actor.valueOf(child.getNodeValue());
+ }
+ concycles.add( new ValidationCycle(name, actor) );
+ }
+ concycles.add( new ValidationCycle() ); // Adds the built-in validation cycle
+
+ if (Database.getMe().isInitialized()) return; // No need to load object type definitions as they are already stored
+
+// Documents tag
+ child = children.get("documents");
+ nlist = child.getChildNodes();
+
+ flows = flist; // Kept for later use in document type definition
+ sclass = clist; // Kept for later use in simulation context type definition
+ mapuse = new LinkedHashMap<String,String>();
+ for (int i=0; i<nlist.getLength(); i++) {
+ child = nlist.item(i);
+ if (!child.getNodeName().equals("article")) continue;
+
+ natr = child.getAttributes();
+ String type = natr.getNamedItem("type").getNodeValue();
+ String uses = null;
+ child = natr.getNamedItem("uses");
+ if (child != null) uses = child.getNodeValue();
+ mapuse.put(type, uses); // Must be added to the map even if no (null) uses
+ }
+// Simulation Contexts tag
+ child = children.get("contexts");
+ nlist = child.getChildNodes();
+
+ context = new Vector<String>();
+ for (int i=0; i<nlist.getLength(); i++) {
+ child = nlist.item(i);
+ if (!child.getNodeName().equals("article")) continue;
+
+ context.add(child.getAttributes().getNamedItem("type").getNodeValue());
+ }
+// Knowledge Elements tag
+ child = children.get("knowledges");
+ nlist = child.getChildNodes();
+
+ kname = new Vector<String>();
+ for (int i=0; i<nlist.getLength(); i++) {
+ child = nlist.item(i);
+ if (!child.getNodeName().equals("article")) continue;
+
+ kname.add(child.getAttributes().getNamedItem("type").getNodeValue());
+ }
+ }
+ catch (Exception error) {
+ logger.info("Error in customization", error);
+ }
+ }
+
+ private void createDocumentTypes () {
+// -----------------------------------
+ DocumentType.Properties tprop = new DocumentType.Properties();
+ HashMap<String,Vector<Step>> mapsteps = new HashMap<String,Vector<Step>>();
+ HashMap<String,Step> mapresult = new HashMap<String,Step>();
+ HashMap<String,DocumentType> maptype = new HashMap<String,DocumentType>();
+
+ Vector<Step> slist = null; // List of Steps to which each document type is valid
+ int snum = 0; // Step number
+ String type = null;
+ String uses = null;
+ for (Iterator<NamedNodeMap> i=flows.iterator(); i.hasNext(); snum++) {
+ NamedNodeMap flow = i.next();
+ Step step = steps.get(snum);
+ String[] contents = flow.getNamedItem("contents").getNodeValue().split(",");
+ for (int j=0; j<contents.length; j++) {
+ type = contents[j];
+ if (!mapuse.containsKey(type)) {
+ logger.warn("Undefined \"" + type + "\" document type.");
+ continue;
+ } slist = mapsteps.get(type);
+ if (slist == null) slist = new Vector<Step>();
+ slist.add(step);
+ mapsteps.put(type, slist);
+ }
+ Node result = flow.getNamedItem("result");
+ if (result != null) mapresult.put(result.getNodeValue(), step);
+ }
+ try {
+ DocumentType tdoc = null;
+ Set<String> tset = mapuse.keySet();
+ Step step;
+ for (Iterator<String> i=tset.iterator(); i.hasNext(); ) {
+ type = i.next();
+ slist = mapsteps.get(type);
+ uses = mapuse.get(type);
+ step = mapresult.get(type);
+
+ tprop.clear();
+ tprop.setName(type).setStep(slist.toArray(new Step[slist.size()]));
+ if (uses != null) {
+ tdoc = maptype.get(uses);
+ if (tdoc == null) logger.warn("Undefined \"" + uses + "\" document type.");
+ else tprop.setUses(tdoc);
+ }
+ if (step != null) tprop.setResult(step);
+
+ tprop.disableCheck();
+ tdoc = Document.createType(tprop); // Creation of Document Types
+ tdoc.approve();
+ maptype.put(type, tdoc);
+ }
+ } catch (Exception error) {
+ logger.warn("Error creating document types, reason:", error); // Should not happen
+ }
+ }
+
+ private void createKnowledgeElementTypes () {
+// -------------------------------------------
+ try {
+ KnowledgeElementType ktype = KnowledgeElement.createType("usecase"); // Internal reserved knowledge element type
+ ktype.reserve();
+ for (Iterator<String> i=kname.iterator(); i.hasNext(); ) {
+ String type = i.next();
+
+ ktype = KnowledgeElement.createType(type); // Knowledge Elements Types defined in the configuration
+ ktype.approve();
+ }
+ } catch (Exception error) {
+ logger.warn("Error creating knowledge types, reason:", error); // Should not happen
+ }
+ }
+
+ private void createSimulationContextTypes () {
+// --------------------------------------------
+ HashMap<String,Step> mapstep = new HashMap<String,Step>();
+ int snum = 0;
+ for (Iterator<NamedNodeMap> i=sclass.iterator(); i.hasNext(); snum++) {
+ NamedNodeMap clatr = i.next();
+ if (clatr == null) continue;
+
+ String[] clist = clatr.getNamedItem("context").getNodeValue().split(",");
+ for (int j=0; j<clist.length; j++) {
+ mapstep.put(clist[j], steps.get(snum));
+ }
+ }
+ try {
+ SimulationContextType tctex = null;
+ for (Iterator<String> i=context.iterator(); i.hasNext(); ) {
+ String type = i.next();
+ if (!mapstep.containsKey(type)) {
+ logger.warn("Could not find \"" + type + "\" classification. Simulation Context type ignored.");
+ continue;
+ }
+ tctex = SimulationContext.createType(type, mapstep.get(type)); // Creation of Simulation Context Types
+ tctex.approve();
+ }
+ } catch (Exception error) {
+ logger.warn("Error creating context types, reason:", error); // Should not happen
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Stand proxy for entities such as Study and Knowledge Element returned by Lucene-based searches.
+ * This interface provides access to properties of searched entities which can be presented in a result search list
+ * before loading the corresponding persistent objects from the database (reason for most properties to be returned as
+ * strings).
+ * One of these properties is the internal persistent identifier of the object represented by a proxy allowing the
+ * user of this interface to load the object from the database.
+ *
+ * @see Database#selectStudiesWhere(Study.Properties...)
+ * @see Database#selectKnowledgeElementsWhere(KnowledgeElement.Properties)
+ * @see Database#selectStudy(int)
+ * @see Database#selectKnowledgeElement(int)
+ * @see Index
+ * @see Index.ObjectProxy
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public interface Proxy {
+
+ public String getAuthorName ();
+
+/**
+ * Returns the internal persistent identifier of the object represented by this proxy. The returned identifier can be used
+ * for selecting the corresponding persistent object from the database.
+ * @return the internal persistent identifier of the object represented by this proxy.
+ */
+ public Integer getIndex ();
+
+ public ProgressState getProgressState ();
+
+/**
+ * Returns the external reference number of the object represented by this proxy. The returned reference is formated
+ * according to the format defined in the configuration file of the application.
+ * @return the external reference number of the object represented by this proxy.
+ */
+ public String getReference ();
+
+ public String getTitle ();
+
+/**
+ * Returns the type of the object represented by this proxy. Depending on the implementation, the returned type may or
+ * may not be localized in the current locale of final user.
+ * @return the type of the object represented by this proxy.
+ */
+ public String getType ();
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.Publication" table="doctag" lazy="false">
+
+<!-- Properties inherited Persistent
+ -->
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+<!-- Publication properties
+ -->
+ <!-- Document mydoc -->
+ <many-to-one name="mydoc" column="doc" access="field" not-null="true" />
+
+ <!-- ProjectElement owner -->
+ <many-to-one name="owner" column="owner" access="field" not-null="true" />
+
+ <!-- char isnew -->
+ <property name="isnew" column="isnew" access="field" not-null="true" />
+
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Publication objects are the way to reference document versions from a Project Element.
+ * As such, a Document version is added (or published) to a Project Element through a Publication object.
+ * This publication is done by saving the Publication object produced when creating and versioning a Document from a given
+ * Project Element Step (call of the saveAs() function).<br/>
+ * <br/>
+ * A Publication object is homogeneous to a reference to a Document version and belongs to one Project Element, this latter
+ * being either a Study Scenario or a Study itself, depending on the Study Step to which the document is published.<br/>
+ * <br/>
+ * The document version referenced by a Publication object is the Value of the publication.
+ *
+ * @see Document
+ * @see ProjectElement
+ * @see Step
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.Session;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.NotApplicableException;
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+import org.splat.kernel.User;
+import org.splat.manox.Reader;
+import org.splat.manox.Toolbox;
+
+
+public class Publication extends Persistent {
+
+// Persistent fields
+ private Document mydoc;
+ private ProjectElement owner; // Either Study or Scenario, depending on the step involved by the publication
+ private char isnew; // True if this references a document version new for the owner project element
+
+// Transient fields
+ private Step mystep;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected Publication () {
+// ------------------------
+ mystep = null;
+ }
+// Internal constructors
+ protected Publication (Document doc, ProjectElement publisher) {
+// --------------------------------------------------------------
+ mydoc = doc;
+ mystep = null;
+ owner = publisher;
+ isnew = 'Y';
+ }
+ protected Publication copy (ProjectElement publisher) {
+// -----------------------------------------------------
+ Publication copy = new Publication();
+ copy.mydoc = this.mydoc;
+ copy.mystep = this.mystep; // May not be initialized yet
+ copy.owner = publisher;
+ copy.isnew = this.isnew;
+ if (!copy.getOwnerStudy().equals(this.getOwnerStudy())) {
+ copy.isnew = 'N'; // The referenced document is not new for the given study
+ }
+ return copy;
+ }
+
+// ==============================================================================================================================
+// Member functions
+// ==============================================================================================================================
+
+ public Relation addDependency (Publication to) {
+// ----------------------------------------------
+ return this.addDependency(to.value());
+ }
+
+ public Relation addDependency (Document to) {
+// -------------------------------------------
+ if (to == null) return null;
+ else return mydoc.addRelation( new UsesRelation(mydoc, to) );
+ }
+
+/**
+ * Undo the out-date operation.
+ *
+ * @return true if the acceptance succeeds
+ * @see #outdate()
+ * @see DocumentRights#canAccept()
+ */
+ public boolean actualize () {
+// ---------------------------
+ if (!this.isOutdated()) return false;
+ isnew = 'Y';
+ Database.getSession().update(this);
+ return true;
+ }
+
+/**
+ * Promotes the document referenced by this publication from In-Check to Approved state, if not out-dated, and attaches the corresponding
+ * time-stamp to the document.</br>
+ * If the promoted document is the final result of the owner study, the study is itself is promoted as well.</br>
+ * </br>
+ * Limitation: the way this promotion is propagated to the study supposes that the study has only ONE final result document.
+ *
+ * @param adate the date of approval
+ * @return true if the approval succeeded
+ * @see #getProgressState()
+ * @see DocumentRights#canApprove()
+ * @see DocumentType#isStudyResult()
+ * @see Study#getApproverOf(Publication)
+ */
+ public Timestamp approve (Date adate) {
+// -------------------------------------
+ if (this.isOutdated()) return null;
+ else if (mydoc.getProgressState() != ProgressState.inCHECK) return null; // This statement must conform to the corresponding right
+
+ DocumentType type = mydoc.getType();
+ Study owner = this.getOwnerStudy();
+ ValidationCycle cycle = owner.getValidationCycleOf(type);
+ User approver = cycle.getActor(ValidationStep.APPROVAL);
+ Timestamp stamp = new Timestamp(ValidationStep.APPROVAL, mydoc, approver, adate);
+ if (!mydoc.promote(stamp)) return null;
+ if (type.isStudyResult() && owner.getProgressState() == ProgressState.inCHECK) owner.promote();
+ return stamp; // Hoping that promotion of the study succeeded
+ }
+
+ public ConvertsRelation attach (String format) {
+// ----------------------------------------------
+ return mydoc.attach(format);
+ }
+
+ public ConvertsRelation attach (String format, String description) {
+// ------------------------------------------------------------------
+ return mydoc.attach(format, description);
+ }
+
+/**
+ * Demotes the document referenced by this publication to In-Work state, and removes the Promoter of the document, if exist.</br>
+ * The In-Draft state is skipped (direct demotion to In-Work) if the validation cycle of the document does not include the review step.</br>
+ * If the demoted document is the final result of the owner study, the study is itself is demoted as well.</br>
+ * </br>
+ * Limitation: the way this demotion is propagated to the study supposes that the study has only ONE final result document.
+ *
+ * @return true if the demotion succeeded
+ * @see #getProgressState()
+ * @see DocumentRights#canDemote()
+ * @see DocumentType#isStudyResult()
+ */
+ public boolean demote () {
+// ------------------------
+ DocumentType type = mydoc.getType();
+ Study owner = this.getOwnerStudy();
+
+ if (mydoc.getProgressState() == ProgressState.inCHECK) {
+ ValidationCycle cycle = owner.getValidationCycleOf(type);
+ if (cycle.enables(ValidationStep.REVIEW)) {
+ if (!mydoc.demote()) return false;
+ } else {
+ if (!mydoc.demote()) return false;
+ mydoc.demote();
+ }
+ } else
+ if (mydoc.getProgressState() == ProgressState.inDRAFT) {
+ if (!mydoc.demote()) return false;
+ } else {
+ return false;
+ }
+ if (type.isStudyResult() && owner.getProgressState() != ProgressState.inWORK) owner.demote();
+ return true;
+ }
+
+/**
+ * Returns the study Step into which the document version referenced by this publication has been published.
+ */
+ public Step getInvolvedStep () {
+// ------------------------------
+ if (mystep == null) {
+ Step[] step = owner.getSteps();
+ for (int i=0; i<step.length; i++) {
+ mystep = step[i]; // The involved step necessarily exists
+ if (mydoc.isInto(mystep)) break;
+ }
+ }
+ return mystep;
+ }
+
+/**
+ * Returns either the Study Scenario or the Study itself to which this publication belongs, depending on the Study Step into
+ * which the referenced document has been published.<br/>
+ * If this publication belongs to a Study, the Project Element returned is the Study returned by getOwnerStudy().
+ *
+ * @return the Study Scenario or the Study to which this publication belongs to
+ * @see #getOwnerStudy()
+ */
+ public ProjectElement getOwner () {
+// ---------------------------------
+ return owner;
+ }
+
+ public Study getOwnerStudy () {
+// -----------------------------
+ if (owner instanceof Study) return (Study)owner;
+ else return ((Scenario)owner).getOwnerStudy();
+ }
+
+/**
+ * Returns the state of this published document.
+ * It is the same than the state of the referenced document, unless this publication is out-of-date, in which case it is
+ * In-Work state.
+ *
+ * @see #outdate()
+ * @see #isOutdated()
+ */
+ public ProgressState getProgressState () {
+// ----------------------------------------
+ if (this.isOutdated()) return ProgressState.inWORK; // Overrides the document state
+ else return mydoc.getProgressState();
+ }
+
+ public List<Publication> getRelations (Class<? extends Relation> type) {
+// ----------------------------------------------------------------------
+ if (type == null) return null;
+
+ List<Publication> result = new ArrayList<Publication>();
+ List<Relation> relist = mydoc.getRelations(type);
+ for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
+ Relation relation = i.next();
+ Document relatedoc = (Document)relation.getTo();
+ Publication related = owner.getPublication(relatedoc);
+ if (related != null) {
+ result.add(related);
+ } else
+ if (owner instanceof Scenario) { // The relation may cross steps belonging to a scenario and its owner study
+ related = ((Scenario)owner).getOwnerStudy().getPublication(relatedoc);
+ if (related != null) result.add(related);
+ }
+ }
+ return result;
+ }
+
+ public File getSourceFile () {
+// ----------------------------
+ return mydoc.getSourceFile();
+ }
+
+/**
+ * Undo the review operation by demoting the document referenced by this publication from In-Check to In-Draft state and
+ * removing the Reviewer.</br>
+ * If the demoted document is the final result of the owner study, the study is itself is demoted as well.</br>
+ * </br>
+ * Limitation: the way this demotion is propagated to the study supposes that the study has only ONE final result document.
+ *
+ * @return true if the demotion succeeded
+ * @see #getProgressState()
+ * @see #review()
+ * @see DocumentRights#canInvalidate()
+ * @see DocumentType#isStudyResult()
+ */
+ public boolean invalidate () {
+// ----------------------------
+ if ( mydoc.getProgressState() != ProgressState.inCHECK ) return false;
+ if (!mydoc.demote()) // Removes the reviewer if this document is In-Check
+ return false;
+ DocumentType type = this.value().getType();
+ Study owner = this.getOwnerStudy();
+ if (type.isStudyResult() && owner.getProgressState() == ProgressState.inCHECK) owner.demote();
+ return true;
+ }
+
+ public boolean isNewForOwner () {
+// -------------------------------
+ return (isnew == 'Y');
+ }
+
+ public boolean isOutdated () {
+// ----------------------------
+ return (isnew == 'O');
+ }
+
+/**
+ * Promotes the document referenced by this publication from In-Work to In-Draft or In-Check state, if not out-dated, and attaches the corresponding
+ * time-stamp to the document.</br>
+ * The In-Draft state is skipped (direct promotion to In-Check) if the validation cycle of the document does not include the review step.</br>
+ * Also, if the promoted document is the final result of the owner study, the study is itself promoted as well.</br>
+ * This operation can be undo-ed by demote().</br>
+ * </br>
+ * Limitation: the way this promotion is propagated to the study supposes that the study has only ONE final result document.
+ *
+ * @return true if the promotion succeeded
+ * @see #getProgressState()
+ * @see #demote()
+ * @see DocumentRights#canPromote()
+ * @see DocumentType#isStudyResult()
+ */
+ public Timestamp promote (Date pdate) {
+// -------------------------------------
+ if (this.isOutdated()) return null;
+ else if (mydoc.getProgressState() != ProgressState.inWORK) return null; // This statement must conform to the corresponding right
+ else {
+ DocumentType type = mydoc.getType();
+ Study owner = this.getOwnerStudy();
+ ValidationCycle cycle = owner.getValidationCycleOf(type);
+ User promoter = cycle.getActor(ValidationStep.PROMOTION);
+ if (promoter == null) promoter = getInvolvedStep().getActor();
+ if (promoter == null) promoter = owner.getAuthor();
+ Timestamp stamp = new Timestamp(ValidationStep.PROMOTION, mydoc, promoter, pdate);
+
+ if (!mydoc.promote(stamp) ) // Promotion to being reviewed
+ return null;
+ if (!cycle.enables(ValidationStep.REVIEW)) {
+ mydoc.promote(null);
+ }
+ if (type.isStudyResult() && owner.getProgressState() == ProgressState.inWORK) owner.promote();
+ return stamp; // Hoping that promotion of the study succeeded
+ }
+ }
+
+ public void rename (String title) throws InvalidPropertyException {
+// ---------------------------------
+ mydoc.rename(title);
+ }
+
+/**
+ * Promotes the document referenced by this publication from In-Draft to In-Check state, if not out-dated, and attaches the corresponding
+ * time-stamp to the document.</br>
+ * If the promoted document is the final result of the owner study, the study is itself is promoted as well.</br>
+ * This operation can be undo-ed by invalidate().</br>
+ * </br>
+ * Limitation: the way this promotion is propagated to the study supposes that the study has only ONE final result document.
+ *
+ * @param rdate the date of review
+ * @return true if the review succeeded
+ * @see #getProgressState()
+ * @see #invalidate()
+ * @see DocumentRights#canReview()
+ * @see DocumentType#isStudyResult()
+ * @see Study#getReviewerOf(Publication)
+ */
+ public Timestamp review (Date rdate) {
+// ------------------------------------
+ if (this.isOutdated()) return null;
+ else if (mydoc.getProgressState() != ProgressState.inDRAFT) return null; // This statement must conform to the corresponding right
+
+ DocumentType type = mydoc.getType();
+ Study owner = this.getOwnerStudy();
+ ValidationCycle cycle = owner.getValidationCycleOf(type);
+ User reviewer = cycle.getActor(ValidationStep.REVIEW);
+ Timestamp stamp = new Timestamp(ValidationStep.REVIEW, mydoc, reviewer, rdate);
+ if (!mydoc.promote(stamp)) return null;
+ if (type.isStudyResult() && owner.getProgressState() == ProgressState.inDRAFT) owner.promote();
+ return stamp; // Hoping that promotion of the study succeeded
+ }
+
+/**
+ * Publishes the document referenced by this publication into the owner Project Element under the given revision number.<br/>
+ * The state of the referenced document is supposed being automatically set according to the given revision number, but, due to the
+ * versioning scheme, as it is not possible to differentiate In-Work and In-Draft states, this function has been deprecated (it is
+ * currently used only for the need of integration of Microsoft Office which anyway has to be redesigned).
+ * <br/>
+ * Note: in the context of branch versioning, the given revision may be modified by an update of the branch name.
+ *
+ * @param newvers the required revision number
+ * @throws FileNotFoundException If the referenced document is empty
+ * @throws NotApplicableException If the referenced document is undefined
+ * @deprecated
+ */
+ public void saveAs (Revision newvers) throws FileNotFoundException, NotApplicableException {
+// -------------------------------------
+ if ( mydoc.isUndefined() ) throw new NotApplicableException("Cannot save a Publication object refering an undefined Document");
+ if (!mydoc.getSourceFile().exists()) throw new FileNotFoundException();
+
+ Database.getSession().save(this); // Must be done before updating the study in order to fix this final (rid-based) hascode
+ mydoc.updateAs(newvers); // May change the branch name of given revision
+ updateOwner();
+ }
+
+/**
+ * Publishes the document referenced by this publication into the owner Project Element under the given state,
+ * the revision number of the document being automatically set accordingly.
+ * If the given state is In-Draft and the document is final result of the owner study, this automatically promotes the study to In-Draft.
+ *
+ * @param state the required progress state
+ * @throws FileNotFoundException If the referenced document is empty
+ * @throws NotApplicableException If the referenced document is undefined
+ */
+ public void saveAs (ProgressState state) throws FileNotFoundException, NotApplicableException {
+// ----------------------------------------
+ if ( mydoc.isUndefined() ) throw new NotApplicableException("Cannot save a Publication object refering an undefined Document");
+ if (!mydoc.getSourceFile().exists()) throw new FileNotFoundException();
+
+ if (state == ProgressState.inWORK || state == ProgressState.EXTERN) {
+ Database.getSession().save(this); // Must be done before updating the study in order to fix this final (rid-based) hascode
+ mydoc.updateAs(state);
+ } else {
+ DocumentType mytype = mydoc.getType();
+ Study owner = this.getOwnerStudy();
+ ValidationCycle cycle = owner.getValidationCycleOf(mytype);
+ boolean review = cycle.enables(ValidationStep.REVIEW);
+ if (!(state == ProgressState.inDRAFT && review) && !(state == ProgressState.inCHECK && !review)) {
+ throw new NotApplicableException("Cannot save a result document in " + state.toString() + " state");
+ }
+ Database.getSession().save(this); // Must be done before updating the study in order to fix this final (rid-based) hascode
+ mydoc.updateAs(ProgressState.inWORK);
+
+ this.promote(mydoc.getLastModificationDate()); // Promotes to the appropriate state in accordance to the validation cycle
+ }
+ updateOwner();
+ }
+
+/**
+ * Out-dates this publication and recursively all publications using this one.
+ * Typically, a publication is out-dated when modifying a document to which it depends.
+ *
+ * @see #isOutdated()
+ * @see #getProgressState()
+ * @see #actualize()
+ */
+ public void outdate () {
+// ----------------------
+ if (this.isOutdated()) return;
+
+ List<Publication> relist = this.getRelations(UsedByRelation.class);
+ for (Iterator<Publication> i = relist.iterator(); i.hasNext(); ) {
+ i.next().outdate();
+ }
+ isnew = 'O';
+ Database.getSession().update(this);
+ }
+
+/**
+ * Returns the document version referenced by this Publication.
+ */
+ public Document value () {
+// ------------------------
+ return mydoc;
+ }
+
+// ==============================================================================================================================
+// Private services
+// ==============================================================================================================================
+
+ private void updateOwner () {
+// ---------------------------
+ Session session = Database.getSession();
+ Step step = this.getInvolvedStep();
+
+// Update of involved step
+ Document previous = mydoc.getPreviousVersion();
+ if (previous != null) {
+ Publication oldoc = step.getDocument(previous.getIndex());
+ boolean done = step.remove(oldoc); // Decrements the configuration tag count of document
+ if (done) session.delete(oldoc); //WARNING: Potential problem because it's not automatically done as orphan object
+ }
+ step.add(this); // Increments the configuration tag count of document
+
+// Import the document properties and update of the study
+ forwardProperties(mydoc.getSourceFile().asFile(), step);
+ session.update(getOwner());
+ }
+
+ private void forwardProperties (java.io.File from, Step to) {
+// -----------------------------------------------------------
+ Reader tool = Toolbox.getReader(from);
+ if (tool == null) return; // No properties extractor available for this type of document
+
+ SimulationContextType.Properties sprop = new SimulationContextType.Properties()
+ .setStep(to.getStep())
+ .setState(ProgressState.APPROVED);
+ List<SimulationContextType> contype = SimulationContext.selectTypesWhere(sprop);
+ if (contype.isEmpty()) return; // No approved property type configured at this step
+
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ List<SimulationContext> context = to.getAllSimulationContexts();
+
+ context = new ArrayList<SimulationContext>(context.size());
+ context.addAll(to.getAllSimulationContexts());
+ cprop.disableCheck();
+ for (Iterator<SimulationContextType> i=contype.iterator(); i.hasNext(); ) {
+ SimulationContextType property = i.next();
+ for (Iterator<SimulationContext> j=context.iterator(); j.hasNext(); ) {
+ SimulationContext existing = j.next();
+ if (!existing.getType().equals(property)) continue;
+ property = null; // Forget this property as it is already set
+ break;
+ }
+ if (property != null) try {
+ String value = tool.extractProperty(property.getName());
+ if (value == null) continue; // Property not defined into the document
+
+ cprop.setType(property).setValue(value);
+ if (owner instanceof Study) ((Study)owner).addProjectContext(cprop); // Re-indexes knowledges and the study
+ else to.addSimulationContext(cprop); // Re-indexes knowledges only
+ } catch (Exception e) {
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ - Mapping of the Relation class hierarchy.
+ - The entire hierarchy is mapped to one single table using a String discriminator.
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+<!-- Uses relation
+ -->
+ <subclass name="org.splat.som.UsesRelation" extends="org.splat.kernel.Relation" discriminator-value="uses">
+ <many-to-one name="refer" column="refer" access="field" not-null="true" />
+ </subclass>
+
+<!-- UsedBy relation
+ -->
+ <subclass name="org.splat.som.UsedByRelation" extends="org.splat.kernel.Relation" discriminator-value="usedby">
+ <many-to-one name="refer" column="refer" access="field" not-null="true" />
+ </subclass>
+
+<!-- Versions relation
+ -->
+ <subclass name="org.splat.som.VersionsRelation" extends="org.splat.kernel.Relation" discriminator-value="versions">
+ <many-to-one name="refer" column="refer" access="field" not-null="true" />
+ </subclass>
+
+<!-- Converts relation
+ -->
+ <subclass name="org.splat.som.ConvertsRelation" extends="org.splat.kernel.Relation" discriminator-value="converts">
+ <many-to-one name="refer" column="refer" access="field" not-null="true" />
+ </subclass>
+
+<!-- Contributor actor relation
+ -->
+ <subclass name="org.splat.som.ContributorRelation" extends="org.splat.kernel.Relation" discriminator-value="contributor">
+ <many-to-one name="refer" column="refer" access="field" not-null="true" />
+ </subclass>
+
+<!-- ValidationCycle relation
+ -->
+ <subclass name="org.splat.som.ValidationCycleRelation" extends="org.splat.kernel.Relation" discriminator-value="cycle">
+<!-- <many-to-one name="refer" column="refer" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />-->
+ <many-to-one name="refer" column="refer" unique="true" access="field" not-null="true" />
+ </subclass>
+
+<!-- Stamp relation
+ -->
+ <subclass name="org.splat.som.StampRelation" extends="org.splat.kernel.Relation" discriminator-value="stamp">
+<!-- <many-to-one name="refer" column="refer" unique="true" cascade="all-delete-orphan" access="field" not-null="true" />-->
+ <many-to-one name="refer" column="refer" unique="true" access="field" not-null="true" />
+ </subclass>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class providing operations on version numbers such as incrementation and comparison.
+ * Revision objects are created from and converted to strings in the internal format of version numbers (major.minor.branch).<br/>
+ * Revision objects can also be created from and converted to strings in user-defined format, thanks to a formating tool
+ * provided by the Format nested class.
+ *
+ * @see Revision.Format
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.nio.CharBuffer;
+import java.text.ParseException;
+
+
+public class Revision {
+
+ private int major;
+ private int minor;
+ private int branch;
+
+ public static class Format {
+// --------------------------
+ private String pattern;
+
+ public Format (String pattern) {
+ this.pattern = pattern;
+ }
+
+ public String format (String verstring) {
+ CharBuffer version = CharBuffer.allocate(pattern.length() + 2*2); // Maximum possible size
+ char[] format = pattern.toCharArray();
+ String[] vernum = verstring.split("\\x2E"); // version is suposed of the internal form (m.n.s)
+ int branch = Integer.valueOf(vernum[2]);
+
+ for (int i=0; i<format.length; i++) {
+ char token = format[i];
+ if (token == '%') {
+ i += 1;
+ token = format[i];
+ if (token == 'M') {
+ version.put(vernum[0]);
+ } else if (token == 'm') {
+ version.put(vernum[1]);
+ } else if (token == 's') {
+ version.put(vernum[2]);
+ }
+ } else if (token == '[') {
+ if (branch == 0) while (format[i] != ']') i += 1;
+ } else if (token == ']') {
+ continue;
+ } else {
+ version.put(token);
+ }
+ }
+ return new String(version.array(), 0, version.position());
+ }
+
+ public Revision parse (String verstring) throws ParseException {
+ char[] format = pattern.toCharArray();
+ char[] version = verstring.toCharArray();
+ CharBuffer major = CharBuffer.allocate(4);
+ CharBuffer minor = CharBuffer.allocate(4);
+ CharBuffer branch = CharBuffer.allocate(4);
+
+ int cursor = 0; // Index into version array
+ for (int i=0; i<format.length; i++) { // The parsed string may not include the branch ID
+ char token = format[i];
+ if (token == '%') {
+ i += 1;
+ token = format[i];
+ if (token == 'M') {
+ while (cursor < version.length) {
+ if (!Character.isDigit(version[cursor])) break;
+ major.put(version[cursor]);
+ cursor += 1;
+ }
+ } else if (token == 'm') {
+ while (cursor < version.length) {
+ if (!Character.isDigit(version[cursor])) break;
+ minor.put(version[cursor]);
+ cursor += 1;
+ }
+ } else if (token == 's') {
+ while (cursor < version.length) {
+ if (!Character.isDigit(version[cursor])) break;
+ branch.put(version[cursor]);
+ cursor += 1;
+ }
+ }
+ } else if (token == '[' || token == ']') {
+ continue;
+ } else {
+ if (version[cursor] != token) throw new ParseException(verstring, cursor);
+ cursor += 1;
+ }
+ if (cursor >= version.length) break;
+ }
+ if (major.position() == 0) throw new ParseException(verstring, 0);
+
+ String majnum = new String(major.array(), 0, major.position());
+ if (minor.position() == 0) {
+ return new Revision(Integer.valueOf(majnum), 0);
+ } else {
+ String minum = new String(minor.array(), 0, minor.position());
+ if (branch.position() == 0) {
+ return new Revision(Integer.valueOf(majnum), Integer.valueOf(minum));
+ } else {
+ String branum = new String(branch.array(), 0, branch.position());
+ return new Revision(Integer.valueOf(majnum), Integer.valueOf(minum), branum);
+ }
+ }
+ }
+
+ public String toPattern () {
+ return pattern;
+ }
+ }
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+/**
+ * Constructs a Revision object from the internal representation of a version number (m.n.s).
+ */
+ public Revision (String value) {
+// ------------------------------
+ String[] vernum = value.split("\\x2E");
+ try {
+ this.major = Integer.valueOf(vernum[0]);
+ this.minor = Integer.valueOf(vernum[1]);
+ this.branch = Integer.valueOf(vernum[2]);
+ }
+ catch (Exception e) { // NumberFormat or OutOfBound exception if value is not of the form m.n.s
+ this.major = 0;
+ this.minor = 0;
+ this.branch = 0;
+ }
+ }
+ public Revision () {
+// ------------------
+ this.major = 0;
+ this.minor = 0;
+ this.branch = 0;
+ }
+ private Revision (int major, int minor) {
+// ---------------------------------------
+ this.major = major;
+ this.minor = minor;
+ this.branch = 0;
+ }
+ private Revision (int major, int minor, String branch) {
+// ------------------------------------------------------
+ this.major = major;
+ this.minor = minor;
+ this.branch = Integer.valueOf(branch);
+ }
+
+// ==============================================================================================================================
+// Public member function
+// ==============================================================================================================================
+
+ public Revision incrementAs (ProgressState state) {
+// -------------------------------------------------
+ if (state == ProgressState.inWORK || state == ProgressState.inDRAFT) minor += 1;
+ else if (state == ProgressState.inCHECK) {
+ major = major + 1;
+ minor = 0;
+ }
+ return this;
+ }
+
+ public boolean isGraterThan (Revision base) {
+// ------------------------------------------
+ if (this.major > base.major) return true;
+ if (this.major < base.major) return false;
+ return (this.minor > base.minor);
+ }
+
+ public boolean isMinor () {
+// -------------------------
+ return (minor != 0);
+ }
+
+ public boolean isNull () {
+// ------------------------
+ return (major+minor == 0);
+ }
+/**
+ * Sets the branch name of this revision.
+ *
+ * @param name the branch name or the internal representation of a version number (m.n.s)
+ * @return this revision object
+ */
+ public Revision setBranch (String name) {
+// ---------------------------------------
+ String[] vernum = name.split("\\x2E");
+
+ branch = Integer.valueOf(vernum[vernum.length-1]);
+ return this;
+ }
+/**
+ * Returns the internal representation of a version number (m.n.s) represented by this Revision object.
+ */
+ public String toString () {
+// -------------------------
+ StringBuffer version = new StringBuffer();
+ return version.append(major).append(".").append(minor).append(".").append(branch).toString();
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <union-subclass name="org.splat.som.Scenario" extends="org.splat.som.ProjectElement" table="scenario" lazy="false">
+
+ <!-- Study owner -->
+ <many-to-one name="owner" column="owner" insert="false" update="false" access="field" not-null="true" />
+
+ <!-- int sid -->
+ <property name="sid" column="sid" access="field" not-null="true" />
+
+ <!-- User cuser -->
+ <many-to-one name="cuser" column="cuser" access="field" />
+
+ <!-- Set<KnowledgeElement> kelms -->
+ <set name="kelms" inverse="true" lazy="false" order-by="`type`,`date` asc" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.som.KnowledgeElement" />
+ </set>
+
+ </union-subclass>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Vector;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.splat.kernel.Persistent;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.User;
+
+
+public class Scenario extends ProjectElement {
+
+// Persistent fields
+ private Study owner;
+ private int sid; // Identifier unique in the scope of owner study
+ private User cuser; // User having checked-out the scenario, if done
+ private Set<KnowledgeElement> kelms;
+
+// Transient fields
+ private HashMap<Integer, List<KnowledgeElement>> known;
+ private List<KnowledgeElement> knowl; // Copy of kelms excluding the internal Knowledge Element (ucase below)
+ private KnowledgeElement ucase; // Internal Knowledge Element for accessing to all used simulation contexts
+
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private Study owner = null;
+ private Scenario previous = null;
+ private Step base = null;
+ private String title = null;
+ private String summary = null;
+ private User manager = null;
+ private Date date = null;
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ owner = null;
+ previous = null;
+ base = null;
+ title = null;
+ summary = null;
+ manager = null;
+ date = null;
+ }
+// - Protected services
+
+ protected Step getBaseStep () {
+ return base; // May be null
+ }
+ protected Scenario getInsertAfter () {
+ return previous; // May be null
+ }
+ protected User getManager () {
+ return manager;
+ }
+ protected Properties setOwnerStudy (Study owner)
+ {
+ this.owner = owner;
+ return this;
+ }
+// - Setters of Scenario properties
+
+ public Properties setBaseStep (Step base) throws InvalidPropertyException
+ {
+ if (!(base.getOwner() instanceof Scenario)) throw new InvalidPropertyException("step");
+ this.base = base;
+ return this;
+ }
+ public Properties setDate (Date date)
+ {
+ this.date = date;
+ return this;
+ }
+ public Properties setDescription (String summary)
+ {
+ if (summary.length() > 0) this.summary = summary;
+ return this;
+ }
+ public Properties setInsertAfter (Scenario previous)
+ {
+ this.previous = previous;
+ return this;
+ }
+ public Properties setManager (User user)
+ {
+ this.manager = user;
+ return this;
+ }
+ public Properties setTitle (String title) throws InvalidPropertyException
+ {
+ if (title.length() == 0) throw new InvalidPropertyException("title");
+ this.title = title;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (owner == null) throw new MissedPropertyException("owner");
+ if (title == null) throw new MissedPropertyException("title");
+ if (manager == null) throw new MissedPropertyException("manager");
+ }
+ }
+// Database fetch constructor
+ protected Scenario () {
+// ---------------------
+ known = null;
+ knowl = null;
+ ucase = null;
+ }
+// Internal constructor
+ protected Scenario (Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// -------------------------------------
+ super(sprop); // Throws one of the above exception if not valid
+ owner = sprop.owner;
+ sid = 0;
+ cuser = null;
+ title = sprop.title; // Inherited attribute
+ known = null;
+ knowl = null; // Initialized when getting all Knowledge Elements
+ ucase = null;
+ kelms = new HashSet<KnowledgeElement>();
+
+ manager = sprop.manager;
+ if (!owner.isStaffedBy(manager)) throw new InvalidPropertyException("manager");
+
+ credate = sprop.date; // Inherited attribute
+ if (credate == null) {
+ Calendar current = Calendar.getInstance();
+ credate = current.getTime(); // Today
+ }
+ lasdate = credate; // Inherited attribute
+
+ if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
+
+ Scenario[] scene = owner.getScenarii();
+ for (int i=0; i<scene.length; i++) if (scene[i].sid > this.sid) this.sid = scene[i].sid;
+ sid += 1;
+ if (sprop.base != null) copyContentsUpTo(sprop.base);
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public KnowledgeElement addKnowledgeElement (KnowledgeElement.Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// -------------------------------------------------------------------------------
+ KnowledgeElement kelm = new KnowledgeElement(kprop.setOwnerScenario(this));
+ Session session = Database.getSession();
+ Transaction transax = session.getTransaction();
+ try {
+ session.save(kelm);
+// Update of my persistent data
+ kelms.add(kelm);
+// Update of my transient data
+ List<KnowledgeElement> known = getKnowledgeElementsOf(kelm.getType()); // Initializes this.known, if not yet done
+ known.add(kelm);
+ if (kelm.getType().equals("usecase")) {
+ ucase = kelm;
+ } else
+ if (knowl != null) { // If null, knowl will be initialized when needed
+ knowl.add(kelm);
+ }
+// Update of the index of Knowledge Elements
+ Database.getIndex().add(kelm);
+ updateMe();
+ return kelm;
+ }
+ catch (RuntimeException e) {
+ if (transax != null && transax.isActive()) {
+// Second try-catch as the rollback could fail as well
+ try {
+ transax.rollback();
+ } catch (HibernateException error) {
+ Study.logger.debug("Error rolling back transaction", error);
+ }
+// Throw again the first exception
+ throw e;
+ }
+ return null;
+ }
+ catch (IOException error) {
+ logger.error("Unable to index the knowedge element '" + kelm.getIndex() + "', reason:", error);
+ return null;
+ }
+ }
+
+ public void checkin () {
+// ----------------------
+ cuser = null;
+ lasdate = Calendar.getInstance().getTime();
+ Database.getSession().update(this);
+ }
+
+ public boolean checkout (User user) {
+// -----------------------------------
+ if (!owner.isStaffedBy(user)) return false;
+
+ cuser = user;
+ lasdate = Calendar.getInstance().getTime();
+ Database.getSession().update(this);
+ return true;
+ }
+
+ public List<KnowledgeElement> getAllKnowledgeElements () {
+// --------------------------------------------------------
+ if (knowl == null) {
+ knowl = new Vector<KnowledgeElement>(kelms.size());
+ for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext(); ) {
+ KnowledgeElement kelm = i.next();
+ if (kelm.getType().equals("usecase")) ucase = kelm;
+ else knowl.add(kelm);
+ }
+ }
+ return Collections.unmodifiableList(knowl);
+ }
+
+ public KnowledgeElement getKnowledgeElement (int index) {
+// -------------------------------------------------------
+ for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext();) {
+ KnowledgeElement mykelm = i.next();
+ if (mykelm.getIndex() == index) return mykelm;
+ }
+ return null;
+ }
+
+ public List<KnowledgeElement> getKnowledgeElementsOf (KnowledgeElementType type) {
+// --------------------------------------------------------------------------------
+ if (kelms.isEmpty()) return new Vector<KnowledgeElement>(); // Smarter than returning null
+ if (known == null) known = new HashMap<Integer, List<KnowledgeElement>>();
+
+ int numtype = type.getIndex();
+ List<KnowledgeElement> listype = known.get(numtype);
+ if (listype == null) {
+ listype = new Vector<KnowledgeElement>();
+ for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext();) {
+ KnowledgeElement kelm = i.next();
+ if (kelm.getType().getIndex() == numtype) listype.add(kelm);
+ }
+ known.put(numtype, listype);
+ }
+ return listype; // No protection against this object corruption as it would not corrupt the database
+ }
+
+ public Study getOwnerStudy () {
+// -----------------------------
+ return owner;
+ }
+/**
+ * Returns the local reference of this scenario. This reference is unique in the scope of the owner study.
+ */
+ public String getReference () {
+// -----------------------------
+ return String.valueOf(sid);
+ }
+
+ public User getUser () {
+// ----------------------
+ return cuser; // Null if the scenario has not been checked-out
+ }
+
+ public boolean removeKnowledgeElement (KnowledgeElement kelm) {
+// -------------------------------------------------------------
+ KnowledgeElement torem = getKnowledgeElement(kelm.getIndex());
+ if (torem == null) return false;
+ boolean done = kelms.remove(torem);
+ if (done) {
+// Update of my transient data
+ List<KnowledgeElement> kelms = known.get(kelm.getType().getIndex());
+ kelms.remove(torem);
+ if (knowl != null) knowl.remove(torem);
+ Database.getSession().update(this);
+//TODO: If the owner study is not private, remove the knowledge from the Lucene index
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isCheckedout () {
+// ------------------------------
+ return (cuser != null);
+ }
+
+ public boolean isEmpty () {
+// -------------------------
+ Step[] mystep = this.getSteps();
+ for (int i=0; i<mystep.length; i++) if (mystep[i].isStarted()) return false;
+ return true;
+ }
+
+ public boolean isFinished () {
+// ----------------------------
+ Step[] mystep = this.getSteps();
+ boolean notempty = false; // If this is empty, this is not finished
+ for (int i=0; i<mystep.length; i++) {
+ if (!mystep[i].isStarted()) continue;
+ if (!mystep[i].isFinished()) return false;
+ notempty = true;
+ }
+ return notempty;
+ }
+
+// ==============================================================================================================================
+// Protected member function
+// ==============================================================================================================================
+
+ protected void updateMyIndex (Index lucin) throws IOException {
+// ------------------------------------------
+ if (ucase == null) for (Iterator<KnowledgeElement> i=kelms.iterator(); i.hasNext(); ) {
+ KnowledgeElement kelm = i.next();
+ if (!kelm.getType().equals("usecase")) continue;
+ ucase = kelm;
+ break;
+ }
+ lucin.update(ucase);
+ }
+
+// ==============================================================================================================================
+// Private services
+// ==============================================================================================================================
+
+ private void copyContentsUpTo (Step lastep) {
+// -------------------------------------------
+ Scenario base = (Scenario)lastep.getOwner();
+ Step[] from = base.getSteps();
+ Step[] to = this.getSteps();
+ for (int i=0; i<from.length; i++) {
+ Step step = from[i];
+ if (step.getNumber() > lastep.getNumber()) break;
+
+ List<Publication> docs = step.getAllDocuments();
+ for (Iterator<Publication> j=docs.iterator(); j.hasNext(); ) {
+ Publication doc = j.next().copy(this); // Creation of a new reference to the document
+// Database.getSession().save(doc); Publications MUST be saved later through cascading when saving the scenario
+ to[i].add(doc);
+ }
+ List<SimulationContext> ctex = step.getAllSimulationContexts();
+ for (Iterator<SimulationContext> j=ctex.iterator(); j.hasNext(); ) {
+ to[i].addSimulationContext(j.next());
+ }
+ }
+ }
+
+ private boolean updateMe () {
+// ---------------------------
+ try {
+ Database.getSession().update(this); // Update of relational base
+ return true;
+ }
+ catch (Exception error) {
+ logger.error("Unable to re-index the knowledge element '" + getIndex() + "', reason:", error);
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.SimulationContext" table="contelm">
+
+<!-- Properties inherited Persistent
+ -->
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+<!-- SimulationContext properties
+ -->
+ <!-- SimulationContextType type -->
+ <many-to-one name="type" column="type" access="field" not-null="true" />
+
+ <!-- int step -->
+ <property name="step" column="step" access="field" not-null="true" />
+
+ <!-- ProgressState state -->
+ <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
+
+ <!-- String value -->
+ <property name="value" column="value" type="text" access="field" not-null="true" />
+
+ <!-- int counter -->
+ <property name="counter" column="counter" access="field" not-null="true" />
+ </class>
+
+<!-- Class SimulationContextType
+ -->
+ <class name="org.splat.som.SimulationContextType" table="contype" lazy="false">
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+ <property name="name" column="name" access="field" not-null="true" />
+ <property name="state" column="state" type="ProgressState" access="field" not-null="true" />
+ <property name="step" column="step" access="field" not-null="true" />
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.hibernate.Session;
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+
+
+public class SimulationContext extends Persistent implements Serializable {
+
+ private SimulationContextType type; // User extendable types
+ private int step;
+ private ProgressState state;
+ private String value;
+ private int counter;
+
+ private static final long serialVersionUID = 422889133378471949L;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private SimulationContextType type = null;
+ private ProjectSettings.Step step = null;
+ private ProgressState state = null;
+ private String value = null;
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ type = null;
+ step = null;
+ state = null;
+ value = null;
+ }
+ protected ProgressState getProgressState () {
+ return state;
+ }
+ public SimulationContextType getType () {
+ return type;
+ }
+ public String getValue () {
+ return value;
+ }
+
+// - Setters of SimulationContext properties
+
+ public Properties setState (ProgressState state) throws InvalidPropertyException
+ {
+ if (state != ProgressState.inCHECK && state != ProgressState.APPROVED) {
+ throw new InvalidPropertyException("state");
+ }
+ this.state = state;
+ return this;
+ }
+ protected Properties setStep (ProjectSettings.Step step) throws InvalidPropertyException
+ {
+ this.step = step;
+ return this;
+ }
+ public Properties setValue (String value) throws InvalidPropertyException
+ {
+ if (value.length() == 0) throw new InvalidPropertyException("value");
+ this.value = value;
+ return this;
+ }
+ public Properties setType (SimulationContextType type)
+ {
+ this.type = type;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity () throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (type == null) throw new MissedPropertyException("type");
+ if (step == null) throw new MissedPropertyException("step");
+ if (value == null) throw new MissedPropertyException("value");
+ if (!type.isAttachedTo(step)) throw new InvalidPropertyException("step");
+ }
+ }
+// Database fetch constructor
+ protected SimulationContext () {
+ }
+// Internal constructor
+ protected SimulationContext (Properties kprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+ super(kprop); // Throws one of the above exception if not valid
+ type = kprop.type;
+ step = kprop.step.getNumber();
+ value = kprop.value;
+ counter = 0;
+ state = kprop.state;
+ if (state == null) state = ProgressState.inCHECK;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean approve () {
+// -------------------------
+ if (state != ProgressState.inCHECK) return false;
+ this.state = ProgressState.APPROVED; // The type name is supposed being localized
+ Database.getSession().update(this);
+ return true;
+ }
+
+ public boolean equals (SimulationContext given) {
+// -----------------------------------------------
+ if (isSaved()) return (this.getIndex() == given.getIndex());
+ if (!this.getType().getName().equals(given.getType().getName())) return false;
+ if (this.getValue().equals(given.getValue())) return true;
+ return false;
+ }
+
+ public String getValue () {
+// -------------------------
+ return value;
+ }
+
+ public ProgressState getProgressState () {
+// ----------------------------------------
+ return state;
+ }
+
+ public SimulationContextType getType () {
+// ---------------------------------------
+ return type;
+ }
+
+ public boolean isInto (Step container) {
+// --------------------------------------
+ return (step == container.getNumber());
+ }
+
+ public boolean isShared () {
+// --------------------------
+ return (counter > 1);
+ }
+
+// ==============================================================================================================================
+// Public services
+// ==============================================================================================================================
+
+ public static SimulationContextType createType (String name, ProjectSettings.Step step) throws InvalidPropertyException, RuntimeException {
+// ---------------------------------------------------------------------------------------
+//TODO: Check for duplicate definition
+ SimulationContextType type = new SimulationContextType(name, step);
+ Session session = Database.getSession();
+ session.save(type);
+
+ return type;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<SimulationContextType> selectAllTypes () {
+// -----------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContextType"); // Useless to order by names as the result mixes localized and non localized types
+ query = query.append(" order by step asc");
+ return Database.getSession().createQuery(query.toString()).list();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<SimulationContextType> selectTypesOf (ProjectSettings.Step... step) {
+// --------------------------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContextType where step='").append(step[0].getNumber()).append("'");
+ for (int i=1; i<step.length; i++) { // Useless to order as the result mixes localized and non localized types
+ query = query.append(" or step='").append(step[i].getNumber()).append("'");
+ }
+ query = query.append(" order by step asc");
+ return Database.getSession().createQuery(query.toString()).list();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static List<SimulationContextType> selectTypesWhere (SimulationContextType.Properties sprop) {
+// ---------------------------------------------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContextType");
+ String separator = " where";
+ ProjectSettings.Step step = sprop.getStep();
+ ProgressState state = sprop.getProgressState();
+ String order = " order by step asc";
+
+ if (step != null) {
+ query = query.append(separator).append(" step='").append(step.getNumber()).append("'");
+ separator = " and";
+ order = " order by state desc"; // APPROVED (upper case A) is grater than inCHECK (lower case i)
+ }
+ if (state != null) {
+ query = query.append(separator).append(" state='").append(state.toString()).append("'");
+// separator = " and";
+ if (step != null) {
+ if (state != ProgressState.APPROVED) order = " order by name asc";
+ else order = ""; // Approved types are localized
+ }
+ }
+ query = query.append(order);
+ return Database.getSession().createQuery(query.toString()).list();
+ }
+
+ public static SimulationContextType selectType (String name) {
+// ------------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContextType where name='").append(name).append("'");
+ return (SimulationContextType)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+ public static SimulationContextType selectType (int index) {
+// ----------------------------------------------------------
+ StringBuffer query = new StringBuffer("from SimulationContextType where rid='").append(index).append("'");
+ return (SimulationContextType)Database.getSession().createQuery(query.toString()).uniqueResult();
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected void hold () {
+// ----------------------
+ counter += 1;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+
+ protected void release () {
+// -------------------------
+ counter -= 1;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.Serializable;
+
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.Persistent;
+
+
+public class SimulationContextType extends Persistent implements Serializable {
+
+// Persistent fields
+ private String name;
+ private ProgressState state;
+ private int step;
+
+// Required by the serialization
+ private static final long serialVersionUID = 4819425038576161242L;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Search properties class
+ public static class Properties {
+// ------------------------------
+ private ProgressState state = null;
+ private ProjectSettings.Step step = null;
+
+ protected ProgressState getProgressState () {
+ return state;
+ }
+ protected ProjectSettings.Step getStep () {
+ return step;
+ }
+ public Properties setState (ProgressState state) {
+ this.state = state;
+ return this;
+ }
+ public Properties setStep (ProjectSettings.Step step) {
+ this.step = step;
+ return this;
+ }
+ }
+// Database fetch constructor
+ protected SimulationContextType () {
+ }
+// Initialization constructor
+ protected SimulationContextType (String name, ProjectSettings.Step step) throws InvalidPropertyException {
+// ------------------------------------------------------------------------
+ super();
+ this.name = name;
+ this.state = ProgressState.inCHECK;
+ this.step = step.getNumber();
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean approve () {
+// -------------------------
+ if (state != ProgressState.inCHECK) return false;
+ this.state = ProgressState.APPROVED; // The type name is supposed being localized
+ Database.getSession().update(this);
+ return true;
+ }
+
+ public boolean equals(Object entity) {
+// ------------------------------------
+ if (entity == null) return false;
+ if (entity instanceof String) {
+ return this.name.equals((String)entity); // Names are unique
+ } else
+ if (entity instanceof SimulationContextType) {
+ SimulationContextType object = (SimulationContextType)entity;
+ int he = object.getIndex();
+ int me = this.getIndex();
+ if (me*he != 0) return (he == me);
+ else return this.getName().equals(object.getName());
+ } else {
+ return false;
+ }
+ }
+
+ public ProjectSettings.Step getAttachedStep () {
+// ----------------------------------------------
+ return ProjectSettings.getStep(step);
+ }
+
+ public String getName () {
+// ------------------------
+ return name;
+ }
+
+ public boolean isAttachedTo (ProjectSettings.Step step) {
+// -------------------------------------------------------
+ if (this.step == step.getNumber()) return true;
+ return false;
+ }
+
+ public boolean isApproved () {
+// ----------------------------
+ return (state == ProgressState.APPROVED);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+
+
+public class StampRelation extends Relation {
+
+ private Timestamp refer;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected StampRelation () {
+ }
+// Internal constructor
+ protected StampRelation (Document from, Timestamp to) {
+// -----------------------------------------------------
+ super(from);
+ this.refer = to;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Timestamp getTo () {
+// -------------------------
+ return refer;
+ }
+
+ public ValidationStep getStampType () {
+// -------------------------------------
+ return refer.getType();
+ }
+
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (Timestamp)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+import java.util.Iterator;
+
+import org.hibernate.Session;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MismatchException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.NotApplicableException;
+import org.splat.kernel.Relation;
+import org.splat.kernel.User;
+import org.splat.som.Database;
+
+
+public class Step {
+
+ private ProjectSettings.Step step;
+ private ProjectElement owner;
+ private List<SimulationContext> contex;
+ private List<Publication> docums;
+ private User actor; // Actor involved in operations on published documents and requiring a time-stamp
+
+// ==============================================================================================================================
+// Constructor
+// ==============================================================================================================================
+
+ protected Step (ProjectSettings.Step step, ProjectElement owner) {
+// ----------------------------------------------------------------
+ this.step = step;
+ this.owner = owner;
+ this.contex = new Vector<SimulationContext>();
+ this.docums = new Vector<Publication>();
+ this.actor = null;
+
+// Filtering of Simulation contexts, if exist
+ for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
+ SimulationContext adoc = i.next();
+ if (!adoc.isInto(this)) continue;
+ this.contex.add(adoc);
+ }
+// Filtering of Documents, if exist
+ for (Iterator<Publication> i=owner.PublicationIterator(); i.hasNext();) {
+ Publication mydoc = i.next();
+ if (!mydoc.value().isInto(this)) continue;
+ this.docums.add(mydoc);
+ }
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Publication createDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException {
+// -------------------------------------------------------------
+ Document newdoc = new Document(dprop.setOwner(owner).setStep(step));
+
+// Creation of the save directory
+ File wdir = newdoc.getSaveDirectory();
+ if (!wdir.exists()) if (!wdir.mkdirs()) throw new IOException("Cannot create the repository vault directory");
+
+// Identification and save
+ newdoc.buildReferenceFrom(getOwnerStudy());
+ Database.getSession().save(newdoc);
+
+ return new Publication(newdoc, owner);
+ }
+
+ public Publication assignDocument (Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, NotApplicableException {
+// -------------------------------------------------------------
+ String refid = dprop.getReference();
+ if (refid == null) return null;
+
+ Document slot = Database.selectDocument(refid, new Revision().toString());
+ if ( slot == null ) return null;
+ if (!slot.isUndefined()) return null; // Should not happen
+
+ slot.initialize(dprop.setOwner(getOwnerStudy()));
+ return new Publication(slot, owner);
+ }
+
+ public Publication versionDocument (Publication base) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
+// -----------------------------------------------------
+ return versionDocument(base, new Document.Properties());
+ }
+
+ public Publication versionDocument (Publication base, String reason) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
+// --------------------------------------------------------------------
+ return versionDocument(base, new Document.Properties().setDescription(reason));
+ }
+
+ public Publication versionDocument (Publication base, Document.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, IOException, MismatchException {
+// --------------------------------------------------------------------------------
+ Document previous = base.value();
+
+ dprop.setDocument(previous); // Initializes the Step property
+ if (dprop.getStep().getNumber() != this.step.getNumber()) throw new MismatchException();
+
+ if (dprop.getAuthor() == null) dprop.setAuthor(previous.getAuthor());
+ String summary = dprop.getDescription();
+
+// Creation of the document
+ Document newdoc = new Document(dprop.setOwner(owner).setStep(step));
+ newdoc.buildReferenceFrom(getOwner(), previous);
+ Database.getSession().save(newdoc);
+
+// Versioning
+ if (summary == null) newdoc.addRelation( new VersionsRelation(newdoc, previous) );
+ else newdoc.addRelation( new VersionsRelation(newdoc, previous, summary) );
+
+// Update of usedby relations, if exist
+ List<Relation> relist = previous.getRelations(UsedByRelation.class);
+ Study scope = getOwnerStudy();
+ for (Iterator<Relation> i=relist.iterator(); i.hasNext();) {
+ UsedByRelation relation = (UsedByRelation)i.next();
+ Document relatedoc = relation.getTo();
+ if (scope.shares(relatedoc)) relatedoc.addRelation( new UsesRelation(relatedoc, newdoc) );
+ else relation.moveTo(newdoc);
+ }
+ return new Publication(newdoc, owner);
+ }
+
+ public SimulationContext addSimulationContext (SimulationContext.Properties dprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+// ----------------------------------------------------------------------------------
+ SimulationContext context = new SimulationContext(dprop.setStep(step));
+ return addSimulationContext(context);
+ }
+
+ public SimulationContext addSimulationContext (SimulationContext context) {
+// -------------------------------------------------------------------------
+ context.hold(); // Increments the reference count of simulation context
+ if (owner.isSaved()) try {
+ Session session = Database.getSession();
+ Index lucin = Database.getIndex();
+
+ if (!context.isSaved()) session.save(context);
+ owner.add(context);
+ contex.add(context); // The context is also referenced from this (transient) Step
+ session.update(owner);
+ updateKnowledgeElementsIndex(lucin);
+ }
+ catch (Exception error) {
+ return null;
+ }
+ else { // Happens when copying a scenario
+ owner.add(context);
+ contex.add(context); // The context is also referenced from this (transient) Step
+// In case of owner scenario, the Knowledge Element index will be updated later, when saving the scenario
+ }
+ return context;
+ }
+
+ public User getActor () {
+// -----------------------
+ return actor;
+ }
+
+ public List<Publication> getAllDocuments () {
+// -------------------------------------------
+ return Collections.unmodifiableList(docums);
+ }
+
+ public List<SimulationContext> getAllSimulationContexts () {
+// ----------------------------------------------------------
+ return Collections.unmodifiableList(contex);
+ }
+
+ public Publication getDocument (int index) {
+// ------------------------------------------
+ for (Iterator<Publication> i=docums.iterator(); i.hasNext();) {
+ Publication found = i.next(); // In a given study step,
+ if (found.value().getIndex() == index) return found; // there is only one publication of a given document
+ }
+ return null;
+ }
+
+ public int getNumber () {
+// -----------------------
+ return step.getNumber();
+ }
+
+ public ProjectElement getOwner () {
+// ---------------------------------
+ return owner; // May be a Study or a Scenario
+ }
+
+ public Study getOwnerStudy () {
+// -----------------------------
+ if (owner instanceof Study) return (Study)owner;
+ else return ((Scenario)owner).getOwnerStudy();
+ }
+
+ public String getPath () {
+// ------------------------
+ return step.getPath();
+ }
+
+ public List<Publication> getResultDocuments () {
+// ----------------------------------------------
+ List<Publication> result = new Vector<Publication>();
+
+ if (!docums.isEmpty()) for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
+ Publication content = i.next();
+ DocumentType type = content.value().getType();
+ if (!type.isResultOf(this.getStep())) continue;
+ result.add(content);
+ }
+ return result;
+ }
+
+ public ProjectSettings.Step getStep () {
+// --------------------------------------
+ return step;
+ }
+
+ public SimulationContext getSimulationContext (int index) {
+// ---------------------------------------------------------
+ for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
+ SimulationContext myctex = i.next();
+ if (myctex.getIndex() == index) return myctex;
+ }
+ return null;
+ }
+
+ public List<SimulationContext> getSimulationContext (SimulationContextType type) {
+// --------------------------------------------------------------------------------
+ Vector<SimulationContext> result = new Vector<SimulationContext>();
+
+ for (Iterator<SimulationContext> i=owner.SimulationContextIterator(); i.hasNext();) {
+ SimulationContext myctex = i.next();
+ if (myctex.getType().equals(type)) result.add(myctex);
+ }
+ return result;
+ }
+
+ public List<DocumentType> getValidDocumentTypes () {
+// --------------------------------------------------
+ return Document.selectTypesOf(step);
+ }
+
+ public boolean isStarted () {
+// ---------------------------
+ if (!step.mayContain(KnowledgeElement.class)) return !docums.isEmpty();
+
+ List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
+ if (kelm.isEmpty() && docums.isEmpty()) return false;
+ return true;
+ }
+
+ public boolean isFinished () {
+// ----------------------------
+ if (!step.mayContain(KnowledgeElement.class)) { // Check if all result documents are approved
+ if (docums.isEmpty()) return false;
+ boolean result = false;
+ for (Iterator<Publication> i=docums.iterator(); i.hasNext(); ) {
+ Document content = i.next().value();
+ DocumentType type = content.getType();
+ if (!type.isResultOf(this.getStep())) continue;
+ if (content.getProgressState() == ProgressState.EXTERN) continue;
+ result = true; // There is at least 1 non external result document
+ if (content.getProgressState() != ProgressState.APPROVED) return false;
+ }
+ return result;
+ }
+ else { // Check if all existing knowledges are approved
+ List<KnowledgeElement> kelm = ((Scenario)owner).getAllKnowledgeElements();
+ if (kelm.isEmpty()) return false;
+ for (Iterator<KnowledgeElement> i=kelm.iterator(); i.hasNext(); ) {
+ KnowledgeElement content = i.next();
+ if (content.getProgressState() != ProgressState.APPROVED) return false;
+ }
+ return true;
+ }
+ }
+
+ public boolean mayContain (@SuppressWarnings("rawtypes") Class type) {
+// --------------------------------------------------------------------
+ return step.mayContain(type);
+ }
+
+ public boolean removeDocument (Publication doctag) {
+// --------------------------------------------------
+ Document value = doctag.value();
+ Publication torem = getDocument(value.getIndex());
+ Session session = Database.getSession();
+
+ if (torem == null) return false;
+
+ this.remove(torem);
+ session.update(owner);
+ if (!value.isPublished() && !value.isVersioned()) { // The referenced document is no more used
+ Set<Relation> links = value.getAllRelations();
+ List<Document> using = new Vector<Document>();
+ for (Iterator<Relation> i=links.iterator(); i.hasNext(); ) {
+ Relation link = i.next();
+ if (link.getClass().equals(ConvertsRelation.class)) { // File conversion
+ session.delete(link.getTo()); // The corresponding physical file is not removed from the vault
+ } else
+ if (link.getClass().equals(UsesRelation.class)) { // Document dependency
+ using.add((Document)link.getTo());
+ }
+ }
+ for (Iterator<Document> i=using.iterator(); i.hasNext(); ) {
+ i.next().removeRelation(UsedByRelation.class, value);
+ }
+ session.delete(value); // The corresponding physical file is not removed from the vault
+ }
+ return true;
+ }
+
+ public boolean removeSimulationContext (SimulationContext context) {
+// ------------------------------------------------------------------
+ SimulationContext torem = getSimulationContext(context.getIndex());
+ Session session = Database.getSession();
+
+ if (torem == null) return false;
+ if (!owner.remove(torem)) return false;
+
+ contex.remove(torem);
+ session.update(owner);
+ if (torem.isShared()) {
+ torem.release();
+ session.update(torem);
+ } else {
+ session.delete(torem);
+ }
+ return true;
+ }
+
+ public void setActor (User user) {
+// --------------------------------
+ actor = user;
+ }
+// ==============================================================================================================================
+// Protected member functions
+// ==============================================================================================================================
+
+ protected boolean add (Publication newdoc) {
+// ------------------------------------------
+ if (!owner.add(newdoc)) return false; // Updates the study in memory
+ docums.add(0, newdoc); // Updates this step
+ newdoc.value().hold(); // Increments the configuration tag count of document
+// If not yet saved, the Publication MUST NOT be saved here, although this creates a temporary inconsistent state into the
+// database (it will be saved later by cascading the update of owner scenario).
+ return true;
+ }
+
+ protected boolean remove (Publication oldoc) {
+// --------------------------------------------
+ if (!owner.remove(oldoc)) return false; // Updates the study in memory
+ docums.remove(oldoc); // Updates this step
+ oldoc.value().release(); // Decrements the configuration tag count of document
+// The publication becoming orphan, it should automatically be removed from the database when updating of owner scenario.
+ return true;
+ }
+
+// ==============================================================================================================================
+// Private services
+// ==============================================================================================================================
+
+ private void updateKnowledgeElementsIndex(Index lucin) {
+// ------------------------------------------------------
+ Scenario[] scenarii;
+ if (owner instanceof Scenario) {
+ scenarii = new Scenario[1];
+ scenarii[0] = (Scenario)owner;
+ } else {
+ scenarii = getOwnerStudy().getScenarii();
+ }
+ try {
+ for (int i=0; i<scenarii.length; i++) {
+ Scenario scene = scenarii[i];
+ List<KnowledgeElement> knelm = scene.getAllKnowledgeElements();
+ for (Iterator<KnowledgeElement> j=knelm.iterator(); j.hasNext(); ) {
+ KnowledgeElement kelm = j.next();
+ lucin.update(kelm);
+ }
+ scene.updateMyIndex(lucin);
+ }
+ }
+ catch (Exception error) {
+// logger.error("Unable to re-index Knowledge Elements, reason:", error);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class defining the default rights related to operations on study steps.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+//TODO: Review this rights according to the state of the owner study.
+
+import org.splat.kernel.User;
+
+
+public class StepRights {
+
+ private User user;
+ private Step operand;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+ public StepRights (User user, Step step) {
+// ----------------------------------------
+ this.user = user;
+ this.operand = step;
+ }
+ public StepRights (Step step) {
+// -----------------------------
+ this.user = step.getOwner().getAuthor();
+ this.operand = step;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+/**
+ * Checks if the user has right to add a comment attached to the selected step.
+ * All actors of the study have such right, including the author, contributors, reviewers and approvers.
+ *
+ * @return true if the user has right to add a comment.
+ */
+ public boolean canAddComment () {
+// -------------------------------
+ Study owner = operand.getOwnerStudy();
+ return (owner.getAuthor().equals(user) || owner.hasActor(user));
+ }
+
+/**
+ * Checks if the user has right to create or import a document into the selected step.
+ * Only the author and contributors have such right, providing that the study step is enabled for writing.
+ *
+ * @return true if the user has right to create or import a document.
+ */
+ public boolean canCreateDocument () {
+// -----------------------------------
+ if (!isEnabled()) return false;
+ return operand.getOwnerStudy().isStaffedBy(user);
+ }
+
+/**
+ * Checks if the user has right to enter a knowledge into the selected step.
+ * Only the author and contributors have such right.
+ *
+ * @return true if the user has right to enter a knowledge.
+ */
+ public boolean canCreateKnowledge () {
+// ------------------------------------
+ return operand.getOwnerStudy().isStaffedBy(user);
+ }
+
+/**
+ * Checks if the user has right to edit the simulation contexts attached to the selected step.
+ * All actors of the study have such right, including the author, contributors, reviewers and approvers.
+ *
+ * @return true if the user has right to edit the simulation contexts.
+ */
+ public boolean canEditSimulationContext () {
+// ------------------------------------------
+ Study owner = operand.getOwnerStudy();
+ return (owner.getAuthor().equals(user) || owner.hasActor(user));
+ }
+
+/**
+ * Checks if the selected step is enabled for writing.
+ * A step may be disabled for writing, or locked, following a check-out of the owner scenario.
+ *
+ * @return true if the step is enabled for writing.
+ */
+ public boolean isEnabled () {
+// ---------------------------
+ ProjectElement owner = operand.getOwner();
+
+ if (owner instanceof Scenario) {
+ Scenario scene = (Scenario)owner;
+ if (scene.isCheckedout()) return false;
+ }
+ return true;
+ }
+
+// ==============================================================================================================================
+// Getters
+// ==============================================================================================================================
+
+ public Step getOperand () {
+// -------------------------
+ return operand;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <typedef name="ProgressState" class="org.splat.kernel.GenericEnumType">
+ <param name="enumClassName">org.splat.som.ProgressState</param>
+ </typedef>
+
+ <typedef name="Visibility" class="org.splat.kernel.GenericEnumType">
+ <param name="enumClassName">org.splat.som.Visibility</param>
+ </typedef>
+
+ <union-subclass name="org.splat.som.Study" extends="org.splat.som.ProjectElement" table="study" lazy="false">
+
+ <!-- String sid -->
+ <property name="sid" column="sid" access="field" not-null="true" />
+
+ <!-- int docount -->
+ <property name="docount" column="docount" access="field" not-null="true" />
+
+ <!-- ProgressState state -->
+ <property name="state" type="ProgressState" column="state" access="field" not-null="true" />
+
+ <!-- Visibility visibility -->
+ <property name="visibility" type="Visibility" column="area" access="field" not-null="true" />
+
+ <!-- List<Scenario> scenarii -->
+ <list name="scenarii" lazy="false" cascade="delete-orphan" access="field">
+ <key column="owner" not-null="true" />
+ <list-index column="scendex"/>
+ <one-to-many class="org.splat.som.Scenario" />
+ </list>
+
+ <!-- String version -->
+ <property name="version" column="version" access="field" not-null="true" />
+
+ <!-- int history -->
+ <property name="history" column="history" access="field" not-null="true" />
+
+ </union-subclass>
+
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.Vector;
+
+import org.hibernate.Session;
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+import org.splat.kernel.User;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.UserDirectory;
+
+
+public class Study extends ProjectElement {
+
+// Persistent fields
+ private String sid; // External unique reference in a format conform to the configuration pattern
+ private int docount; // Total number of documents of this study, including versions
+ private ProgressState state;
+ private Visibility visibility;
+ private List<Scenario> scenarii;
+ private String version;
+ private int history; // Number of studies versioning this one, if any
+
+// Transient fields
+ private List<User> contributor; // Shortcut to contributors
+ private HashMap<String,ValidationCycle> validactor; // Shortcut to validation cycles
+ private Set<User> actor; // Summary of above actors
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ private String sid = null; // Search criterion only
+ private String title = null;
+ private String summary = null;
+ private User manager = null;
+ private User actor = null; // Search criterion only
+ private Visibility visibility = null; // Search criterion only
+ private ProgressState state = null; // Search criterion only
+ private Date date = null;
+ private List<SimulationContext> context = new Vector<SimulationContext>(); // Search criterion only
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ sid = null;
+ title = null;
+ summary = null;
+ manager = null;
+ actor = null;
+ visibility = null;
+ state = null;
+ date = null;
+ context = new Vector<SimulationContext>(); // as clear() may generate side effects
+ }
+ public Properties copy () {
+ Properties copy = new Properties();
+ copy.sid = this.sid;
+ copy.title = this.title;
+ copy.summary = this.summary;
+ copy.manager = this.manager;
+ copy.actor = this.actor;
+ copy.visibility = this.visibility;
+ copy.state = this.state;
+ copy.date = this.date;
+ copy.context = this.context;
+ return copy;
+ }
+// - Protected services
+
+ protected User getActor () {
+ return actor;
+ }
+ protected User getManager () {
+ return manager;
+ }
+ protected ProgressState getProgressState () {
+ return state;
+ }
+ protected String getReference () {
+ return sid;
+ }
+ protected List<SimulationContext> getSimulationContexts () {
+ return context;
+ }
+ protected String getTitle () {
+ return title;
+ }
+ protected Visibility getVisibility () {
+ return visibility;
+ }
+// - Property setters
+
+// For building a search query
+ public Properties setActor (User actor)
+ {
+ this.actor = actor;
+ return this;
+ }
+ public Properties setDate (Date date)
+ {
+ this.date = date;
+ return this;
+ }
+ public Properties setDescription (String summary)
+ {
+ if (summary.length() > 0) this.summary = summary;
+ return this;
+ }
+ public Properties setManager (User user)
+ {
+ this.manager = user;
+ return this;
+ }
+// For building a search query
+ public Properties setReference (String sid) throws InvalidPropertyException
+ {
+ if (sid.length() == 0) throw new InvalidPropertyException("reference");
+ this.sid = sid;
+ return this;
+ }
+// For building a search query
+ public Properties setSimulationContexts (List<SimulationContext> context) {
+ this.context = context;
+ return this;
+ }
+// For building a search query
+ public Properties setState (ProgressState state)
+ {
+ this.state = state;
+ return this;
+ }
+ public Properties setTitle (String title) throws InvalidPropertyException
+ {
+ if (title.length() == 0) throw new InvalidPropertyException("title");
+ this.title = title;
+ return this;
+ }
+// For building a search query
+ public Properties setVisibility (Visibility area)
+ {
+ this.visibility = area;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity() throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException
+ {
+ if (title == null) throw new MissedPropertyException("title");
+ if (manager == null) throw new MissedPropertyException("manager");
+ }
+ }
+// Database fetch constructor
+ protected Study () {
+// ------------------
+ contributor = null;
+ validactor = null;
+ actor = null;
+ }
+// Internal constructor
+ protected Study (Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// ----------------------------------
+ super(sprop); // Throws one of the above exception if not valid
+ sid = ProjectSettings.getReferencePattern(); // Reset after save
+ title = sprop.title; // Inherited attribute
+ manager = sprop.manager;
+ docount = 0;
+ history = 0;
+ scenarii = new LinkedList<Scenario>();
+ visibility = Visibility.PRIVATE;
+ state = ProgressState.inWORK;
+
+ credate = sprop.date; // Inherited attribute
+ if (credate == null) {
+ Calendar current = Calendar.getInstance();
+ credate = current.getTime(); // Today
+ }
+ lasdate = credate; // Inherited attribute
+ version = new Revision().incrementAs(state).toString();
+
+ if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
+
+ contributor = null;
+ validactor = null;
+ actor = null;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean addContributor (User user) {
+// -----------------------------------------
+ if (contributor == null) this.setShortCuts(); // Initializes contributor
+ for (Iterator<User> i=contributor.iterator(); i.hasNext(); ) {
+ User present = i.next();
+ if ( present.equals(user) ) return false;
+ }
+ boolean absent = actor.add(user); // User may already be a reviewer or an approver
+
+ this.addRelation( new ContributorRelation(this, user) );
+ if (absent) updateMe(); // Else, useless to re-index the study
+ contributor.add(user);
+ return true;
+ }
+
+ public SimulationContext addProjectContext (SimulationContext.Properties cprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+// -------------------------------------------------------------------------------
+ SimulationContext added = this.getFirstStep().addSimulationContext(cprop);
+ updateMe();
+ return added;
+ }
+
+ public SimulationContext addProjectContext (SimulationContext context) {
+// ----------------------------------------------------------------------
+ SimulationContext added = this.getFirstStep().addSimulationContext(context);
+ updateMe();
+ return added;
+ }
+
+ public Scenario addScenario (Scenario.Properties sprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException, RuntimeException {
+// -------------------------------------------------------
+ if (sprop.getManager() == null) sprop.setManager(this.manager);
+
+ Scenario scenario = new Scenario(sprop.setOwnerStudy(this));
+ Scenario previous = sprop.getInsertAfter();
+ Session session = Database.getSession();
+
+ if (previous == null) {
+ scenarii.add(scenario);
+ } else {
+ scenarii.add(scenarii.indexOf(previous)+1, scenario);
+ }
+ session.update(this); // No need to update the Lucene index
+ session.save(scenario); // Must be done after updating this study because of the back reference to the study
+ if (sprop.getBaseStep() != null) {
+// No need to update the Knowledge Element index as Knowledge Elements are not copied
+ scenario.refresh(); // Because saving the scenario changes the hashcode of copied Publications
+ }
+ KnowledgeElementType ucase = KnowledgeElement.selectType("usecase");
+ KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
+ User admin = UserDirectory.selectUser(1); // First user created when creating the database
+ kprop.setType(ucase)
+ .setTitle(this.getTitle())
+ .setValue(scenario.getTitle())
+ .setAuthor(admin); // Internal Knowledge Element required by the validation process of knowledges
+ scenario.addKnowledgeElement(kprop);
+ return scenario;
+ }
+
+/**
+ * Returns all actors of this study other than the author, including contributors, reviewers and approvers.
+ *
+ * @return the actors of this study
+ * @see #hasActor(User)
+ */
+ public Set<User> getActors () {
+// -----------------------------
+ if (actor == null) setShortCuts();
+ return Collections.unmodifiableSet(actor);
+ }
+
+ public List<User> getContributors () {
+// ------------------------------------
+ if (contributor == null) setShortCuts();
+ return Collections.unmodifiableList(contributor); // May be empty
+ }
+
+ public ProgressState getProgressState () {
+// ----------------------------------------
+ return state;
+ }
+
+/**
+ * Returns the global unique reference of this study.
+ * The study reference is common to all versions of the study (versioning a study does not change its reference).
+ * The form of this study reference is defined in the configuration of the application server - see the SOM XML customization
+ * file.
+ */
+ public String getReference () {
+// -----------------------------
+ return sid;
+ }
+
+ public Scenario[] getScenarii () {
+// --------------------------------
+ return scenarii.toArray(new Scenario[scenarii.size()]);
+ }
+
+/**
+ * Returns the validation cycle of the given document type.
+ *
+ * @param doc the document type being subject of validation
+ * @return the validation cycle of the document, or null if not defined.
+ */
+ public ValidationCycle getValidationCycleOf (DocumentType type) {
+// ---------------------------------------------------------------
+ if (validactor == null) setShortCuts();
+ ValidationCycle result = validactor.get(type.getName());
+ if (result == null) {
+ if (type.isStepResult()) result = validactor.get("default"); // "default" validation cycle defined in the configuration, if exist
+ if (result == null) result = validactor.get("built-in");
+ }
+ return result;
+ }
+
+ public String getVersion () {
+// ---------------------------
+ return version;
+ }
+
+ public Visibility getVisibility () {
+// ----------------------------------
+ return visibility;
+ }
+
+/**
+ * Checks if the given user is actor of this study.
+ * Actors include contributors, reviewers and approvers.
+ *
+ * @return true if the given user is actor of this study.
+ * @see #getActors()
+ */
+ public boolean hasActor (User user) {
+// -----------------------------------
+ if (user == null) return false;
+ for (Iterator<User> i=this.getActors().iterator(); i.hasNext(); ) {
+ User involved = i.next();
+ if (involved.equals(user)) return true;
+ }
+ return false;
+ }
+
+/**
+ * Checks whether this study is in the Public or the Reference area of the repository.
+ *
+ * @return true if the study is public.
+ * @see #moveToPublic()
+ * @see #moveToReference()
+ */
+ public boolean isPublic () {
+// --------------------------
+ return (visibility != Visibility.PRIVATE);
+ }
+/**
+ * Checks if the given user participates to this study.
+ * The Study staff includes the author and contributors.
+ *
+ * @return true if the given user is actor of this study.
+ * @see #getContributors()
+ */
+ public boolean isStaffedBy (User user) {
+// --------------------------------------
+ if (user == null) return false;
+ if (manager.equals(user)) return true;
+ for (Iterator<User> i=getContributors().iterator(); i.hasNext();) {
+ if (i.next().equals(user)) return true;
+ }
+ return false;
+ }
+
+ public boolean isVersioned () {
+// -----------------------------
+ return (history > 0);
+ }
+
+/**
+ * Moves this study from the Private to the Public area of the repository.
+ *
+ * @return true if the move succeeded.
+ * @see #isPublic()
+ */
+ public boolean moveToPublic () {
+// ------------------------------
+ if (visibility != Visibility.PRIVATE) return false;
+
+ this.visibility = Visibility.PUBLIC;
+ if ( updateMe() ) {
+ return updateKnowledgeElementsIndex(); // If fails, the database roll-back is under responsibility of the caller
+ }
+ return false;
+ }
+
+/**
+ * Moves this study from the Public to the Reference area of the repository.
+ * For being moved to the Reference area, the study must previously be approved.
+ *
+ * @return true if the move succeeded.
+ * @see #moveToPublic()
+ * @see #isPublic()
+ * @see Publication#approve(Date)
+ */
+ public boolean moveToReference () {
+// ---------------------------------
+ if (state != ProgressState.APPROVED) return false;
+ if (visibility != Visibility.PUBLIC) return false;
+
+ this.visibility = Visibility.REFERENCE;
+ if ( updateMe() ) {
+ return updateKnowledgeElementsIndex(); // If fails, the database roll-back is under responsibility of the caller
+ }
+ return false;
+ }
+
+ public boolean publishes (Document doc) {
+// ---------------------------------------
+ if (!super.publishes(doc)) {
+ Scenario[] scene = this.getScenarii();
+ for (int i=0; i<scene.length; i++) {
+ if (scene[i].publishes(doc)) return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean removeContributor (User... users) {
+// ------------------------------------------------
+ if (contributor == null) this.setShortCuts(); // Initializes contributor
+ Boolean done = false;
+ for (int i=0; i<users.length; i++) {
+ User user = users[i];
+ for (Iterator<User> j=contributor.iterator(); j.hasNext(); ) {
+ User present = j.next();
+ if (!present.equals(user)) continue;
+
+ this.removeRelation(ContributorRelation.class, user);
+ j.remove(); // Updates the contributor shortcut
+ done = true;
+ break;
+ }
+ }
+ if (done) updateMe();
+ return done;
+ }
+
+ public boolean removeProjectContext (SimulationContext context) {
+// ---------------------------------------------------------------
+ boolean done = this.getFirstStep().removeSimulationContext(context);
+ updateMe();
+ return done;
+ }
+
+ public void setValidationCycle (DocumentType type, ValidationCycle.Properties vprop) {
+// ------------------------------------------------------------------------------------
+ if (validactor == null) setShortCuts(); // Initializes validactor and actor
+
+ String cname = type.getName();
+ ValidationCycle cycle = validactor.get(cname);
+
+ if (cycle != null && cycle.isAssigned()) {
+ cycle.resetActors(vprop);
+ } else
+ try {
+ cycle = new ValidationCycle(this, vprop.setDocumentType(type));
+
+ ValidationCycleRelation link = cycle.getContext();
+ this.addRelation(link);
+ validactor.put(cname, link.getTo()); // Replaces the cycle if exists as default,
+ }
+ catch (Exception error) {
+ logger.error("Unable to re-index Knowledge Elements, reason:", error);
+ return;
+ }
+ resetActorsShortCut();
+ updateMe(); // Re-index the study, just in case
+ }
+
+ public boolean shares (Document doc) {
+// ------------------------------------
+ Scenario[] scene = this.getScenarii(); // If shared from within the study, the document is shared by the scenarios
+ int counter = 0;
+
+ for (int i=0; i<scene.length; i++) {
+ if (!scene[i].publishes(doc)) continue;
+ if (counter == 1) return true;
+ counter += 1;
+ }
+ return false;
+ }
+
+ public boolean update (Properties sprop) throws InvalidPropertyException {
+// ----------------------------------------
+ if (sprop.title != null) this.title = sprop.title;
+ if (sprop.summary != null) this.setAttribute( new DescriptionAttribute(this, sprop.summary) );
+//TODO: To be completed
+ return updateMe();
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected boolean buildReference () {
+// -----------------------------------
+ String pattern = getReference(); // The study being supposed just created, its reference is the reference pattern
+ IDBuilder tool = Database.selectIDBuilder(credate);
+ if (tool == null) {
+ tool = new IDBuilder(credate);
+ Database.getSession().save(tool);
+ }
+ this.sid = tool.buildReference(pattern, this);
+ return true;
+ }
+
+/**
+ * Demotes this study from In-Check to In-Draft then In-Work states.
+ * This function is called internally when demoting the final result document of the study.
+ *
+ * @return true if the demotion succeeded.
+ */
+ protected boolean demote () {
+// ---------------------------
+ if (state == ProgressState.inCHECK) state = ProgressState.inDRAFT;
+ else if (state == ProgressState.inDRAFT) state = ProgressState.inWORK;
+ else return false;
+ return updateMe();
+ }
+
+ protected int generateLocalIndex () {
+// -----------------------------------
+ docount = docount + 1;
+ Database.getSession().update(this);
+ return docount;
+ }
+
+ protected int getLastLocalIndex () {
+// ----------------------------------
+ return docount;
+ }
+
+ protected void loadWorkflow () {
+// ------------------------------
+ setShortCuts();
+ }
+/**
+ * Promotes this study from In-Work to In-Draft then In-Check and APPROVED states.
+ * This function is called internally when promoting the final result document of the study.
+ *
+ * @return true if the demotion succeeded.
+ */
+ protected boolean promote () {
+// ----------------------------
+ if (state == ProgressState.inWORK) {
+ state = ProgressState.inDRAFT;
+ } else
+ if (state == ProgressState.inDRAFT) {
+ this.state = ProgressState.inCHECK;
+ Revision myvers = new Revision(version);
+ if (myvers.isMinor()) {
+ version = myvers.incrementAs(state).toString();
+ }
+ } else
+ if (state == ProgressState.inCHECK) {
+ state = ProgressState.APPROVED;
+ }
+ else return false;
+
+ return updateMe();
+ }
+
+// ==============================================================================================================================
+// Private member functions
+// ==============================================================================================================================
+
+ private void resetActorsShortCut () {
+// -----------------------------------
+ actor.clear();
+// Get all actors involved in validation cycles
+ for (Iterator<ValidationCycle> i=validactor.values().iterator(); i.hasNext(); ) {
+ ValidationCycle cycle = i.next();
+ User[] user = cycle.getAllActors();
+ for (int j=0; j<user.length; j++) actor.add(user[j]);
+ }
+// Get all other actors
+ for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
+ Relation link = i.next();
+ Class<?> kindof = link.getClass().getSuperclass();
+ if (!kindof.equals(ActorRelation.class)) continue;
+ actor.add( ((ActorRelation)link).getTo() );
+ }
+ }
+
+ private void setShortCuts () {
+// ----------------------------
+ contributor = new Vector<User>();
+ validactor = new HashMap<String,ValidationCycle>();
+ actor = new HashSet<User>();
+
+// Get the contributors
+ for (Iterator<Relation> i=getRelations(ContributorRelation.class).iterator(); i.hasNext(); ) {
+ ContributorRelation link = (ContributorRelation)i.next();
+ contributor.add(link.getTo());
+ }
+// Get the validation cycles specific to this study
+ for (Iterator<Relation> i=getRelations(ValidationCycleRelation.class).iterator(); i.hasNext(); ) {
+ ValidationCycleRelation link = (ValidationCycleRelation)i.next();
+ validactor.put(link.getDocumentType().getName(), link.getTo()); // The associated document type is necessarily not null in this context
+ }
+// Get the validation cycles coming from the configured workflow and not overridden in this study
+ for (Iterator<ProjectSettings.ValidationCycle> i=ProjectSettings.getAllValidationCycles().iterator(); i.hasNext(); ) {
+ ProjectSettings.ValidationCycle cycle = i.next();
+ String type = cycle.getName();
+ if (!validactor.containsKey(type)) validactor.put(type, new ValidationCycle(this, cycle));
+ }
+// Get all corresponding actors
+ for (Iterator<ValidationCycle> i=validactor.values().iterator(); i.hasNext(); ) {
+ ValidationCycle cycle = i.next();
+ User[] user = cycle.getAllActors();
+ for (int j=0; j<user.length; j++) actor.add(user[j]);
+ }
+// Get all other actors
+ for (Iterator<Relation> i=this.getAllRelations().iterator(); i.hasNext(); ) {
+ Relation link = i.next();
+ Class<?> kindof = link.getClass().getSuperclass();
+ if (!kindof.equals(ActorRelation.class)) continue;
+ actor.add( ((ActorRelation)link).getTo() );
+ }
+ }
+
+ private boolean updateKnowledgeElementsIndex() {
+// ----------------------------------------------
+ try {
+ Index lucin = Database.getIndex();
+
+ for (Iterator<Scenario> i=scenarii.iterator(); i.hasNext(); ) {
+ Scenario scene = i.next();
+ for (Iterator<KnowledgeElement> j=scene.getAllKnowledgeElements().iterator(); j.hasNext(); ) {
+ KnowledgeElement kelm = j.next();
+ lucin.update(kelm);
+ }
+ }
+ return true;
+ }
+ catch (Exception error) {
+ logger.error("Unable to re-index Knowledge Elements, reason:", error);
+ return false;
+ }
+ }
+
+ private boolean updateMe () {
+// ---------------------------
+ try {
+ Database.getSession().update(this); // Update of relational base
+ Database.getIndex().update(this); // Update of Lucene index
+ return true;
+ }
+ catch (Exception error) {
+ logger.error("Unable to re-index the study '" + getIndex() + "', reason:", error);
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class defining the default rights related to operations on studies.
+ * On the contrary of documents, a study cannot directly be reviewed or approved. It is reviewed or approved through
+ * its final report.
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.User;
+
+
+public class StudyRights {
+
+ private User user;
+ private Study operand;
+ private boolean author = false; // For optimizing
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+ public StudyRights (User user, Study study) {
+// -------------------------------------------
+ this.user = user;
+ this.operand = study;
+ this.author = operand.getAuthor().equals(user); // user may be null
+ }
+ public StudyRights (Study study) {
+// --------------------------------
+ this.user = study.getAuthor();
+ this.operand = study;
+ this.author = true; // In order to ignore the author in this context
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public boolean canAddScenario () {
+// --------------------------------
+ if (operand.getProgressState() != ProgressState.inWORK && operand.getProgressState() != ProgressState.inDRAFT) return false;
+ return operand.isStaffedBy(user);
+ }
+
+/**
+ * Checks if the user has right to edit the description of the study.
+ * All actors of the study have such right, including the author, contributors, reviewers and approvers.
+ *
+ * @return true if the user has right to edit the description.
+ */
+ public boolean canEditDescription () {
+// ------------------------------------
+ return (operand.getAuthor().equals(user) || operand.hasActor(user));
+ }
+
+ public boolean canEditProperties () {
+// -----------------------------------
+ return author;
+ }
+
+/**
+ * Checks if the user has right to move the study from the Private to the Public area of the repository.
+ * Only the author of the study have such right.
+ *
+ * @return true if the user has right to edit the description.
+ */
+ public boolean canPublish () {
+// ----------------------------
+ if (!author) return false;
+ return (!operand.isPublic());
+ }
+
+ public boolean canPurge () {
+// --------------------------
+ if (!author) return false;
+ return operand.isVersioned();
+ }
+
+ public boolean canRemove () {
+// ---------------------------
+ if (operand.getProgressState() != ProgressState.inWORK && operand.getProgressState() != ProgressState.inDRAFT) return false;
+ return author;
+ }
+
+ public boolean canVersion () {
+// ----------------------------
+ if (operand.getProgressState() != ProgressState.inWORK && operand.getProgressState() != ProgressState.inDRAFT) return false;
+ return operand.isStaffedBy(user);
+ }
+
+// ==============================================================================================================================
+// Getter
+// ==============================================================================================================================
+
+ public Study getOperand () {
+// --------------------------
+ return operand;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <typedef name="StampType" class="org.splat.kernel.GenericEnumType">
+ <param name="enumClassName">org.splat.som.ValidationStep</param>
+ </typedef>
+
+ <class name="org.splat.som.Timestamp" table="stamp" lazy="false">
+
+<!-- Properties inherited from Any
+ -->
+ <id name="rid" type="int" column="rid" unsaved-value="0" access="field">
+ <generator class="org.splat.kernel.IDGenerator"/>
+ </id>
+ <set name="attributes" inverse="true" lazy="false" cascade="all-delete-orphan" access="field">
+ <key column="owner" />
+ <one-to-many class="org.splat.kernel.Attribute" />
+ </set>
+
+<!-- Timestamp properties
+ -->
+ <!-- StampRelation context -->
+ <one-to-one name="context" property-ref="refer" access="field" />
+
+ <!-- ValidationCycle.Step mytype -->
+ <property type="StampType" name="mytype" column="type" access="field" not-null="true" />
+
+ <!-- User author -->
+ <many-to-one name="author" column="author" access="field" not-null="true" />
+
+ <!-- Date sdate, including the time section -->
+ <property type="timestamp" name="sdate" column="date" access="field" not-null="true" />
+
+ </class>
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.Comparator;
+import java.util.Date;
+
+import org.splat.kernel.Any;
+import org.splat.kernel.Attribute;
+import org.splat.kernel.User;
+
+
+public class Timestamp extends Any {
+
+ private StampRelation context;
+ private ValidationStep mytype;
+ private User author;
+ private Date sdate;
+
+ public static class ComparatorByDate implements Comparator<Timestamp> {
+// ---------------------------------------------------------------------
+ public int compare(Timestamp t1, Timestamp t2)
+ {
+ return t1.getDate().compareTo(t2.getDate());
+ }
+ }
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected Timestamp () {
+ }
+// Internal constructors
+ protected Timestamp (ValidationStep type, Document from, User to, Date sdate) {
+// -----------------------------------------------------------------------------
+ super((Attribute)null); // For building the collection of attributes
+ this.mytype = type;
+ this.author = to;
+ this.sdate = sdate;
+ this.context = new StampRelation(from, this);
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public User getAuthor () {
+// ------------------------
+ return author;
+ }
+
+ public String getComment () {
+// ---------------------------
+ CommentAttribute field = (CommentAttribute)this.getAttribute(CommentAttribute.class);
+ String result = null;
+ if (field != null) result = field.getValue();
+ return result;
+ }
+
+ public Date getDate () {
+// ----------------------
+ return sdate;
+ }
+
+ public ValidationStep getType () {
+// --------------------------------
+ return mytype;
+ }
+
+ public void setComment (String comment) {
+// ---------------------------------------
+ if (comment != null) this.setAttribute( new CommentAttribute(this, comment) );
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected StampRelation getContext () {
+// -------------------------------------
+ return context;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+
+
+public class UsedByRelation extends Relation {
+
+ private Document refer;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected UsedByRelation () {
+ }
+// Initialization constructors
+ protected UsedByRelation (Document from, Document to) {
+// -----------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.reverse = new UsesRelation(this, to, from);
+ }
+// Internal constructor
+ protected UsedByRelation (Relation back, Document from, Document to) {
+// --------------------------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.reverse = back;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Class<? extends Relation> getReverseClass () {
+// ---------------------------------------------------
+ return UsesRelation.class;
+ }
+ public Document getTo () {
+// -------------------------
+ return refer;
+ }
+ public boolean isBidirectional () {
+// ---------------------------------
+ return true;
+ }
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (Document)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+
+
+public class UsesRelation extends Relation {
+
+ private Document refer;
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected UsesRelation () {
+ }
+// Initialization constructors
+ protected UsesRelation (Document from, Document to) {
+// ---------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.reverse = new UsedByRelation(this, to, from);
+ }
+// Internal constructor
+ protected UsesRelation (Relation back, Document from, Document to) {
+// ------------------------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.reverse = back;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public Class<? extends Relation> getReverseClass () {
+// ---------------------------------------------------
+ return UsedByRelation.class;
+ }
+
+ public Document getTo () {
+// -------------------------
+ return refer;
+ }
+ public boolean isBidirectional () {
+// ---------------------------------
+ return true;
+ }
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (Document)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+<!--
+ -
+ - @author Daniel Brunier-Coulin
+ - @copyright OPEN CASCADE 2012
+ -->
+
+<hibernate-mapping>
+
+ <class name="org.splat.som.ValidationCycle" table="cycle" lazy="false">
+
+<!-- Properties inherited Persistent
+ -->
+ <id name="rid" column="rid" access="field">
+ <generator class="increment"/>
+ </id>
+
+<!-- ValidationCycle properties
+ -->
+ <!-- ValidationCycleRelation context -->
+ <one-to-one name="context" property-ref="refer" access="field" />
+
+ <!-- DocumentType mytype -->
+ <many-to-one name="mytype" column="type" access="field" not-null="true" />
+
+ <!-- User publisher -->
+ <many-to-one name="publisher" column="publisher" access="field" />
+
+ <!-- User reviewer -->
+ <many-to-one name="reviewer" column="reviewer" access="field" />
+
+ <!-- User approver -->
+ <many-to-one name="approver" column="approver" access="field" />
+
+ <!-- User signatory -->
+ <many-to-one name="signatory" column="signatory" access="field" />
+
+ </class>
+</hibernate-mapping>
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ * Class defining the validation cycle applicable to documents of a given type.<br/>
+ * A validation cycle specifies the validation steps of documents complying with by this cycle, as well as the actors
+ * involved in such validations. Once past, each validation step is written down by a time-stamp attached to the validated
+ * document.<br/>
+ * <br/>
+ * The possible validation steps are Promotion, Review, Approval and Acceptance (or Refusal), all being optional,
+ * except Promotion.<br/>
+ * When enabled, Review and Approval involve one given user while Promotion and Acceptance have default actors defined by
+ * the application. The default actors are:
+ * <ul>
+ * <li>Promotion by either the author of the document or the responsible of study</li>
+ * <li>Acceptance by the customer, possibly represented by an internal user</li>
+ * </ul>
+ * Explicit Promotion and Acceptance actors can be defined, for example to force some documents to be published by the
+ * responsible of study only.<br/>
+ * <br/>
+ * Default validation cycles are defined in the configuration workflow, the responsible of studies overriding them when necessary.
+ * They are attached to studies at a given document type.<br/>
+ *
+ * @see Study#addValidationCycle(DocumentType,Properties)
+ * @see Study#getValidationCycleOf(DocumentType)
+ * @see Timestamp
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import java.util.List;
+import java.util.Vector;
+
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.MissedPropertyException;
+import org.splat.kernel.MultiplyDefinedException;
+import org.splat.kernel.Persistent;
+import org.splat.kernel.User;
+import org.splat.kernel.UserDirectory;
+
+public class ValidationCycle extends Persistent {
+
+ private ValidationCycleRelation context;
+ private DocumentType mytype; // Null if the referenced validation cycle is a default one
+ private User publisher;
+ private User reviewer; // Null if no REVIEW validation step
+ private User approver; // Null if no APPROVAL validation step
+ private User signatory; // Null if no ACCEPTANCE validation step
+
+ public enum Actor {
+ manager, // Responsible of study
+ Nx1, // N+1 manager of the responsible of study
+ Nx2, // N+2 manager of the responsible of study
+ customer // Customer
+ }
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Fields initialization class
+ public static class Properties extends Persistent.Properties {
+// ------------------------------------------------------------
+ DocumentType doctype = null;
+ User publisher = null;
+ User reviewer = null;
+ User approver = null;
+ User signatory = null;
+
+// - Public services
+
+ public void clear () {
+ super.clear();
+ doctype = null;
+ publisher = null;
+ reviewer = null;
+ approver = null;
+ signatory = null;
+ }
+// - Protected services
+
+ protected Properties setDocumentType (DocumentType type)
+ {
+ doctype = type;
+ return this;
+ }
+// - Properties setter
+
+ public Properties setActor (ValidationStep step, User actor)
+ {
+ if (step == ValidationStep.PROMOTION) publisher = actor;
+ else if (step == ValidationStep.REVIEW) reviewer = actor;
+ else if (step == ValidationStep.APPROVAL) approver = actor;
+ else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) signatory = actor;
+ return this;
+ }
+// - Global validity check
+
+ public void checkValidity() throws MissedPropertyException
+ {
+ if (doctype == null) throw new MissedPropertyException("type");
+ }
+ }
+// Database fetch constructor
+ protected ValidationCycle () {
+ }
+// Internal constructors
+ protected ValidationCycle (Study from, ProjectSettings.ValidationCycle cycle) {
+// -----------------------------------------------------------------------------
+ Actor[] actype = cycle.getActorTypes();
+ User.Properties uprop = new User.Properties();
+
+ mytype = Document.selectType(cycle.getName()); // Null in case of default validation cycle
+// context = new ValidationCycleRelation(from, this);
+ context = null; // Validation cycle defined in the workflow
+ for (int i=0; i<actype.length; i++) {
+ User actor = null;
+ if (actype[i] != null)
+ try {
+ if (actype[i] == Actor.manager) {
+ actor = from.getAuthor();
+ } else
+ if (actype[i] == Actor.Nx1) {
+ List<User> manager = UserDirectory.selectUsersWhere(uprop.setOrganizationName("Nx1"));
+ if (manager.size() == 1) actor = manager.get(0);
+ } else
+ if (actype[i] == Actor.Nx2) {
+ List<User> manager = UserDirectory.selectUsersWhere(uprop.setOrganizationName("Nx2"));
+ if (manager.size() == 1) actor = manager.get(0);
+ } else { /* Actor.customer */
+ actor = from.getAuthor();
+//TODO: Get the customer of the study, if exists
+ }
+ } catch (Exception e) { // Should not happen
+ actor = null;
+ }
+ if (i == 0) reviewer = actor;
+ else if (i == 1) approver = actor;
+ else if (i == 2) signatory = actor;
+ }
+ }
+ protected ValidationCycle (Study from, Properties vprop) throws MissedPropertyException, InvalidPropertyException, MultiplyDefinedException {
+// --------------------------------------------------------
+ super(vprop); // Throws one of the above exception if not valid
+ mytype = vprop.doctype;
+ publisher = vprop.publisher; // May be null
+ reviewer = vprop.reviewer; // May be null
+ approver = vprop.approver; // May be null
+ signatory = vprop.signatory; // May be null
+ context = new ValidationCycleRelation(from, this);
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+/**
+ * Checks if a given validation step is enabled in this validation cycle.
+ *
+ * @param step the validation step checked.
+ * @return true if the given validation step is enabled.
+ */
+ public boolean enables (ValidationStep step) {
+// -------------------------------------------
+ if (step == ValidationStep.PROMOTION) return true;
+ else if (step == ValidationStep.REVIEW) return (reviewer != null);
+ else if (step == ValidationStep.APPROVAL) return (approver != null);
+ else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) return (signatory != null);
+ return false;
+ }
+
+/**
+ * Returns the user involved in a given step of this document validation cycle.
+ * When enabled, the Review and Approval steps have one explicit actor returned by this function. On the other hand,
+ * Promotion and Acceptance have default actors - they respectively are the author of the document or the responsible of study,
+ * and the customer or its representative internal user. In this context, a null user is returned.
+ *
+ * @param step the validation step
+ * @return the user involved by the given step or null if the step is disabled or the actors are the default ones
+ * @see #getAllActors()
+ * @see #enables
+ */
+ public User getActor (ValidationStep step) {
+// -----------------------------------------
+ if (step == ValidationStep.PROMOTION) return publisher;
+ else if (step == ValidationStep.REVIEW) return reviewer;
+ else if (step == ValidationStep.APPROVAL) return approver;
+ else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) return signatory;
+ return null;
+ }
+
+/**
+ * Returns all explicit actors of this document validation cycle, that is, actors of enabled validation cycles, excluding
+ * the default actors.
+ *
+ * @return the users explicitly involved by the steps of this validation cycle
+ * @see #getActor(ValidationStep)
+ * @see #enables(ValidationStep)
+ */
+ public User[] getAllActors () {
+// -----------------------------
+ Vector<User> result = new Vector<User>();
+ if (publisher != null) result.add(publisher);
+ if (reviewer != null) result.add(reviewer);
+ if (approver != null) result.add(approver);
+ if (signatory != null) result.add(signatory);
+ return result.toArray(new User[result.size()]);
+ }
+
+/**
+ * Return the document type to which this validation cycle applies. If this validation cycle is a default one, the document
+ * type is not defined.
+ *
+ * @return the document type involved by this validation cycle, or null if this validation cycle is a default one.
+ * @see #isDefault()
+ */
+ public DocumentType getDocumentType () {
+// --------------------------------------
+ return mytype; // May be null
+ }
+
+/**
+ * Checks if this validation cycle is assigned to a study. If not, it is common to all studies of the workflow in which it has
+ * been defined.
+ *
+ * @return true if this validation cycle is assigned to a study.
+ */
+ public boolean isAssigned () {
+// ----------------------------
+ return (context != null);
+ }
+
+/**
+ * Checks if this validation cycle is a default one, either specific to a Study or defined in the configuration workflow or
+ * built-in.<br/>
+ * Default validation cycle are not attached to any document type. As for built-in ones, they doesn't include any validation step
+ * other than Promotion.
+ *
+ * @return true if this validation cycle is a default one.
+ * @see #getDocumentType()
+ * @see ProjectSettings#getNewValidationCycle()
+ */
+ public boolean isDefault () {
+// ---------------------------
+ return (mytype == null);
+ }
+
+// ==============================================================================================================================
+// Protected services
+// ==============================================================================================================================
+
+ protected ValidationCycleRelation getContext () {
+// -----------------------------------------------
+ return context;
+ }
+
+ protected void remove (ValidationStep step) {
+// ------------------------------------------
+ if (step == ValidationStep.REVIEW) reviewer = null;
+ else if (step == ValidationStep.APPROVAL) approver = null;
+ else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) signatory = null;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+
+ protected void resetActors (Properties vprop) {
+// ---------------------------------------------
+ publisher = vprop.publisher; // May be null
+ reviewer = vprop.reviewer; // May be null
+ approver = vprop.approver; // May be null
+ signatory = vprop.signatory; // May be null
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+
+ protected void setActor (ValidationStep step, User actor) {
+// --------------------------------------------------------
+ if (step == ValidationStep.PROMOTION) publisher = actor;
+ else if (step == ValidationStep.REVIEW) reviewer = actor;
+ else if (step == ValidationStep.APPROVAL) approver = actor;
+ else if (step == ValidationStep.ACCEPTANCE || step == ValidationStep.REFUSAL) signatory = actor;
+ if (this.isSaved()) Database.getSession().update(this);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+
+
+public class ValidationCycleRelation extends Relation {
+
+ private ValidationCycle refer;
+
+// ==============================================================================================================================
+// Construction
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected ValidationCycleRelation () {
+ }
+// Internal constructor
+ protected ValidationCycleRelation (Study from, ValidationCycle to) {
+// ------------------------------------------------------------------
+ super(from);
+ this.refer = to;
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+/**
+ * Returns the document type to which the validation cycle referenced by this relation applies. If the referenced validation cycle
+ * is a default one, the associated document type is not defined.
+ *
+ * @return the document type involved by the referenced validation cycle, or null if this latter is a default one.
+ */
+ public DocumentType getDocumentType () {
+// --------------------------------------
+ return refer.getDocumentType();
+ }
+
+ public ValidationCycle getTo () {
+// -------------------------------
+ return refer;
+ }
+
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (ValidationCycle)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public enum ValidationStep {
+ PROMOTION, REVIEW, APPROVAL, ACCEPTANCE, // Validation steps subject of time stamp
+ DISTRIBUTION, REFUSAL // Additional Time stamps
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+import org.splat.kernel.Persistent;
+import org.splat.kernel.Relation;
+
+
+public class VersionsRelation extends Relation {
+
+// Persistent field
+ private Document refer;
+
+// Transient fields
+ private boolean got; // For optimizing getDescription()
+ private String description; // Null if this is not described
+
+// ==============================================================================================================================
+// Constructors
+// ==============================================================================================================================
+
+// Database fetch constructor
+ protected VersionsRelation () {
+// -----------------------------
+ got = false;
+ description = null;
+ }
+// Initialization constructors
+ protected VersionsRelation (Document from, Document to) {
+// -------------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.got = true;
+ this.description = null; // Conversion not described
+ }
+ protected VersionsRelation (Document from, Document to, String description) {
+// ---------------------------------------------------------------------------
+ super(from);
+ this.refer = to;
+ this.got = true;
+ this.description = description; // May be null
+ if (description != null) this.setAttribute( new DescriptionAttribute(this, description) );
+ }
+
+// ==============================================================================================================================
+// Public member functions
+// ==============================================================================================================================
+
+ public String getDescription () {
+// -------------------------------
+ if (!got) {
+ DescriptionAttribute field = (DescriptionAttribute)this.getAttribute(DescriptionAttribute.class);
+ if (field != null) description = field.getValue();
+ got = true; // Don't need to be modified later as set and remove attribute functions are private to this class
+ }
+ return description; // May be null
+ }
+
+ public Document getTo () {
+// -------------------------
+ return refer;
+ }
+ protected void setTo (Persistent to) {
+// ------------------------------------
+ refer = (Document)to;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.splat.som;
+/**
+ *
+ * @author Daniel Brunier-Coulin
+ * @copyright OPEN CASCADE 2012
+ */
+
+public enum Visibility {
+ PRIVATE, // Qualifies studies stored into the private area
+ PUBLIC, // Qualifies studies stored into the public area
+ REFERENCE // Qualifies studies stored into the reference area
+}
\ No newline at end of file
--- /dev/null
+name.module = Centre d''études
+
+size.format = #,##0 Ko
+date.format = dd/MM/yyyy
+dd/MM/yyyy = jj/mm/aaaa
+
+menu.step.1 = Spécifier l''étude
+menu.step.2 = Concevoir le scénario
+menu.step.3 = Créer la géométrie
+menu.step.4 = Générer le modèle d''analyse
+menu.step.5 = Entrer les conditions de calcul
+menu.step.6 = Effectuer le calcul
+menu.step.7 = Analyser les résultats
+menu.step.8 = Capitaliser ce cas d''étude
+menu.step.9 = Finaliser l''étude
+
+folder.step.1 = Spécification de l''étude
+folder.step.2 = Description du scénario
+folder.step.3 = Géométrie
+folder.step.4 = Modèle d''analyse
+folder.step.5 = Conditions de calcul
+folder.step.6 = Schéma de calcul
+folder.step.7 = Résultats
+folder.step.8 = Élements de connaissances
+folder.step.9 = Rapport final
+
+type.document.requirements = Cahier des charges
+type.document.specification = Document de spécification
+type.document.design = Document de conception
+type.document.geometry = Géométrie
+type.document.model = Modèle d''analyse
+type.document.loads = Conditions de calcul
+type.document.script = Script d''exécution
+type.document.log = Log d''exécution
+type.document.results = Résultats de calcul
+type.document.report = Rapport final
+type.document.memorandum = Note technique
+type.document.minutes = Compte rendu
+
+type.context.customer = Client
+type.context.product = Produit
+type.context.phase = Phase du produit
+type.context.need = Besoin client
+type.context.purpose = Finalité de l''étude
+type.context.physic = Type de physique
+type.context.object = Objet étudié
+type.context.part = Objet modélisé
+type.context.geometry = Type de géométrie
+type.context.model = Type de modèle
+type.context.element = Type d''éléments
+type.context.shape = Géométrie des éléments
+type.context.order = Degré des éléments
+type.context.analysis = Type d''analyse
+type.context.platform = Plate-forme logicielle
+type.context.module = Module de calcul
+type.context.component = Brique technologique
+
+type.knowledge.bestpractice = Bonne pratique
+type.knowledge.limitation = Limitation
+type.knowledge.inconsistency = Incohérence
+type.knowledge.metrics = Métrique
+type.knowledge.improvement = Amélioration
+
+history.creation = Document créé par
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project-structure>
+
+
+<!-- 1. Database physical location
+ The database includes an SQL base containing the studies and the document metadata, a Lucene index used for searching studies and
+ knowledges, a file vault including all actual data and a directory where files uploaded and downloaded by users are temporarily saved.
+ All these information are located in sub-directories of a common root directory defined below.
+ This directory must be visible from the server application (Tomcat).
+ -->
+ <database>
+ <repository disk="C:/Repository" />
+ </database>
+
+
+<!-- 2. Formats
+ -->
+ <formats>
+
+<!-- 2.1 Project elements identification scheme
+ Studies, Knowledges and Documents are identified by unique user references. The structure of these references is customizable.
+ You customize references through patterns.
+ A reference's pattern is a character string including format directives. These format directives allow you to insert
+ some information into the reference. The following directives are available:
+ - %yy or %yyyy for inserting the entity creation year on 2 or 4 digits
+ - %0000 for inserting a unique index, the number of digits being defined by the number of 0
+ The above index is unique in the scope of cycle defined by the first format directive (year). In other words, this index
+ restarts every new year. As such, for making references unique on this application server, both format directives (cycle
+ and index) must be present in the pattern.
+ Other characters are simply inserted as is in generated references. They can be used for extending the reference uniqueness
+ beyond application servers, by adding a prefix specific to a given server (for example, a company department name).
+ Given that these references may be used as directory or file names of the repository vault, the pattern must not include
+ illicit characters such as '/', '?', '<', '>' etc.
+ -->
+ <references study="DER%yy%0000"/>
+
+<!-- 2.2 Physical files naming scheme
+ The physical data files stored into the repository vault can be named as follows:
+ - By the user-defined title of corresponding documents ("title" name attribute below)
+ - Encoded by a built-in scheme ("encoded" name attribute)
+ - As is, that is, by keeping the name of the imported file ("asis" name attribute - not yet supported)
+ Remarks:
+ - When using the title scheme, as file names may include accent characters, client browsers must be configured for
+ NOT encoding URLs as UTF-8.
+ - Whatever is the naming scheme used, in order to avoid name clashes, file names are anyway suffixed by an index
+ unique in the scope of the owner study.
+ -->
+ <files name="encoded"/>
+
+<!-- 2.3 Document versions format
+ Defines the format in which version numbers are presented to users.
+ A version number includes a major, a minor and a branch number, when exist.
+ -->
+ <versions pattern="%M.%m[-%s]"/>
+ </formats>
+
+
+<!-- 3. Study step types
+ The user activities involved in studies are defined by study step types. The tag below simply lists all possible steps
+ applicable in a workflow.
+ Step types are defined by type names used in the API for accessing to study activities.
+ The document data produced during these activities are saved into the repository vault. They can be structured in
+ sub-directories of each study root directory. As such, the definition of study step types includes the path of the
+ corresponding sub-directory.
+ The list below does not define the order of steps - this order is specified by the workflow. The steps are listed in
+ an order defining the internal index of steps. These index are used for localizing the activity names and corresponding
+ folder names.
+
+ Remark:
+ - "scenario" is a reserved type name.
+ -->
+ <steps>
+ <article type="specification" path="1.Study"/>
+ <article type="design" path="1.Study"/>
+ <article type="modeling" path="2.Geometry"/>
+ <article type="meshing" path="3.Mesh"/>
+ <article type="preprocessing" path="4.Load"/>
+ <article type="solving" path="5.Result"/>
+ <article type="postprocessing" path="6.Analysis"/>
+ <article type="capitalization" path="7.Knowledge"/>
+ <article type="reporting" path="1.Study"/>
+ </steps>
+
+
+<!-- 4. Document types
+ All documents under the control of the Study Manager are typed. The tag below simply lists all possible document types
+ involved in a workflow.
+ Document types are defined by type names used in the API for manipulating document types. These type names are also used
+ for localizing document types.
+ The documents have dependencies in accordance to their type. As such, the definition of each document type include the
+ potential dependencies of corresponding documents.
+
+ Warning: Articles must be ordered in a way that dependent document types (uses attribute values) must previously be defined.
+ Example: "requirements" type must be defined before "specification" because "specification" uses "requirements".
+ Remarks:
+ - The dependencies are transitive (if document A depends on document B, itself depending on C, A implicitly depends on C).
+ - "knowledge" is a reserved word qualifying Knowledge Elements. So, it must not be used as a document type name.
+ - "default" and "built-in" are also reserved words used for defining validation cycles.
+ - In this version, the "uses" attribute is limited to 1 document type only.
+ -->
+ <documents>
+ <article type="requirements"/>
+ <article type="specification" uses="requirements"/>
+ <article type="design" uses="specification"/>
+ <article type="geometry" uses="design"/>
+ <article type="model" uses="geometry"/>
+ <article type="loads" uses="model"/>
+ <article type="script" uses="loads"/>
+ <article type="log" uses="script"/>
+ <article type="results" uses="script"/>
+ <article type="report" uses="results"/>
+ <article type="memorandum"/>
+ <article type="minutes"/>
+ </documents>
+
+
+<!-- 5. Simulation Context types
+ As documents, the simulation contexts are typed. The tag below simply lists the simulation context types available initially,
+ after the installation of the product. These types can then be extended on the fly by end-users when assigning simulation
+ contexts to studies.
+ Simulation context types are defined by type names used in the API for manipulating simulation contexts. These type names
+ are also used for localizing simulation contexts types.
+
+ Warning: The Simulation Context type "product" is mandatory as it is used when creating a study.
+ -->
+ <contexts>
+
+ <!-- General information -->
+ <article type="customer"/>
+ <article type="product"/>
+ <article type="phase"/> <!-- Phase of the product -->
+ <article type="need"/> <!-- Customer needs -->
+ <article type="purpose"/> <!-- Objective of the study -->
+ <article type="physic"/> <!-- Structure analysis, Thermal-hydraulics, Neutronic... -->
+
+ <!-- Geometry characteristics Examples: -->
+ <article type="object"/> <!-- Car, Plane, Equipment... -->
+ <article type="part"/> <!-- Crankcase, Outer layer... -->
+ <artivle type="geometry"/> <!-- Surface, Volume -->
+
+ <!-- Model characteristics Examples: -->
+ <article type="model"/> <!-- CSG, FEM... -->
+ <article type="element"/> <!-- Bar, Surface, Volume -->
+ <article type="shape"/> <!-- (Surface) Triangle, Quadrangle... (Volume) Tetrahedron, Hexahedron... -->
+ <article type="order"/> <!-- First-order, Second-order... -->
+
+ <!-- Analysis type Examples: -->
+ <article type="analysis"/> <!-- Static, Dynamic... -->
+
+ <!-- Software tools used -->
+ <article type="platform"/>
+ <article type="module"/>
+ <article type="component"/>
+ </contexts>
+
+
+<!-- 6. Knowledge Elements types
+ As documents and simulation contexts, the knowledges are typed. The tag below lists these knowledge types.
+ Knowledge types are simply defined by type names used in the API for manipulating knowledge types. These type names
+ are also used for localizing knowledge types.
+
+ Warning: The Knowledge Elements type "usecase" is reserved for internal use.
+ -->
+ <knowledges>
+ <article type="bestpractice"/>
+ <article type="limitation"/>
+ <article type="inconsistency"/>
+ <article type="metrics"/>
+ <article type="improvement"/>
+ </knowledges>
+
+
+<!-- 7. User activities
+
+ Remarks:
+ - Step names must naturally be unique.
+ - Simulation Contexts must be attached to one classification step only.
+ - Result document types must be results of one step only and be part of contents of the corresponding step.
+ -->
+ <activities>
+ <step name="specification">
+ <classification context="customer,product,phase,need,purpose,physic"/>
+ <flow contents="requirements,specification,minutes" result="specification"/>
+ <storage path="1.Study"/>
+ </step>
+ <scenario>
+ <step name="design">
+ <flow contents="design,memorandum,minutes" result="design"/>
+ <storage path="1.Study"/>
+ </step>
+ <step name="modeling">
+ <classification context="object,part,geometry"/>
+ <flow contents="geometry,memorandum,minutes" result="geometry"/>
+ <storage path="2.Geometry"/>
+ </step>
+ <step name="meshing">
+ <classification context="model,element,shape,order"/>
+ <flow contents="model,memorandum,minutes" result="model"/>
+ <storage path="3.Mesh"/>
+ </step>
+ <step name="preprocessing">
+ <classification context="analysis"/>
+ <flow contents="loads,script,minutes" result="loads"/>
+ <storage path="4.Analysis"/>
+ </step>
+ <step name="solving">
+ <classification context="platform,module,component"/>
+ <flow contents="log,results,minutes" result="results"/>
+ <storage path="5.Result"/>
+ </step>
+ <step name="postprocessing">
+ <flow contents="memorandum,minutes"/>
+ <storage path="6.Report"/>
+ </step>
+ <step name="capitalization">
+ <flow contents="knowledge"/>
+ <storage path="6.Report"/>
+ </step>
+ </scenario>
+ <step name="reporting">
+ <flow contents="report,minutes" result="report"/>
+ <storage path="1.Study"/>
+ </step>
+ </activities>
+
+
+<!-- 8. Document validation cycles
+ Validation cycles define the actors involved in the validation steps of documents. These steps can be
+ "review", "approval" and "acceptance".
+ Remarks:
+ - Each validation cycle is defined by a tag corresponding to the type of an activity result document.
+ - The actors of validation steps can be
+ "manager", referring the responsible of study,
+ "Nx1", referring the manager of the department (see User definition for more information),
+ "Nx2", referring the boss of the department manager,
+ "customer" (most likely involved in the acceptance step).
+ -->
+ <validations>
+ <specification review="Nx1" approval="Nx2"/>
+ <report review="Nx1" approval="Nx2"/>
+ <default review="manager" />
+ </validations>
+
+</project-structure>
\ No newline at end of file
--- /dev/null
+name.module = Study Manager
+
+size.format = #,##0 Kb
+date.format = MM.dd.yyyy
+MM.dd.yyyy = mm.dd.yyyy
+
+menu.step.1 = Specify the study
+menu.step.2 = Design the scenario
+menu.step.3 = Create the geometry
+menu.step.4 = Generate the analysis model
+menu.step.5 = Enter the boundary conditions
+menu.step.6 = Execute the calculation
+menu.step.7 = Analyze the results
+menu.step.8 = Capitalize this use-case
+menu.step.9 = Finalize the study
+
+folder.step.1 = Specification of the study
+folder.step.2 = Description of the scenario
+folder.step.3 = Geometry
+folder.step.4 = Analysis model
+folder.step.5 = Boundary conditions
+folder.step.6 = Calculation scheme
+folder.step.7 = Calculation results
+folder.step.8 = Knowledge elements
+folder.step.9 = Final report
+
+type.document.requirements = Customer requirements
+type.document.specification = Specification document
+type.document.design = Design document
+type.document.geometry = Geometry
+type.document.model = Analysis model
+type.document.loads = Boundary conditions
+type.document.script = Execution script
+type.document.log = Execution log
+type.document.results = Calculation results
+type.document.report = Final report
+type.document.memorandum = Technical report
+type.document.minutes = Minute meeting
+
+type.context.customer = Customer
+type.context.product = Product
+type.context.phase = Product phase
+type.context.need = Customer needs
+type.context.purpose = Purpose of study
+type.context.physic = Physics
+type.context.object = Studied object
+
+type.context.part = Modeled object
+type.context.geometry = Geometry type
+type.context.model = Type of analysis model
+type.context.element = Element type
+type.context.shape = Geometry of elements
+type.context.order = Order of elements
+type.context.analysis = Analysis type
+type.context.platform = Software platform
+type.context.module = Solver
+type.context.component = Software component
+
+type.knowledge.bestpractice = Best practice
+type.knowledge.limitation = Limitation
+type.knowledge.inconsistency = Inconsistency
+type.knowledge.metrics = Metrics
+type.knowledge.improvement = Improvement
+
+history.creation = Document created by
\ No newline at end of file
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
-http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
-http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+http://www.springframework.org/schema/tx
+http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
+
</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<study ref="PLM110001">
+
+ <properties title="Évaluation de la dose flash"
+ user="ffe"
+ date="03/05/2011" />
+
+ <contexts>
+ <context type="product" value="LMJ"/>
+ </contexts>
+
+ <step name="specification">
+ <document ref="PLM110001.01">
+ <properties title="Cahier des charges" type="requirements" format="pdf" author="ffe" date="03/05/2011" state="EXTERN" />
+ </document>
+ <document ref="PLM110001.02">
+ <properties title="Spécifications générales" type="specification" format="xml" author="ffe" date="10/05/2011" state="inDRAFT" />
+ <relations>
+ <uses ref="PLM110001.01"/>
+ </relations>
+ </document>
+ </step>
+ <scenario title="Neutronique">
+ <step name="modeling">
+ <document ref="PLM110001.03">
+ <properties title="Assemblage PCC" type="geometry" format="ProE" author="ffe" date="10/05/2011" state="inDRAFT" />
+ <relations>
+ <uses ref="PLM110001.02"/>
+ </relations>
+ </document>
+ </step>
+ </scenario>
+ <scenario title="Activation">
+ </scenario>
+ <scenario title="Photonique">
+ </scenario>
+
+</study>
\ No newline at end of file
--- /dev/null
+package test;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.splat.som.*;
+import org.splat.kernel.Do;
+import org.splat.kernel.UserDirectory;
+import org.splat.kernel.User;
+import org.splat.kernel.Role;
+import org.splat.manox.Reader;
+import org.splat.manox.Toolbox;
+import org.splat.manox.Writer;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.apache.log4j.Logger;
+
+
+public class Test {
+
+ final static Logger logger = Logger.getLogger(Test.class);
+
+// ==============================================================================================================================
+// Main
+// ==============================================================================================================================
+
+ public static void main(String[] args) {
+// --------------------------------------
+ Session session = Database.getSession(); // Single session for multiple operations
+ Transaction transax = session.beginTransaction();
+
+ ProjectSettings project = ProjectSettings.getMe();
+ String path = System.getProperty("user.dir");
+ try {
+ project.configure(path + "/src/som.xml");
+ }
+ catch (Exception error) {
+ logger.fatal("Could not initialize the database, reason:", error);
+ return;
+ }
+ int nargs = args.length;
+ if (nargs > 0) switch (Integer.valueOf(args[0])) {
+
+ case 1:
+ if (!importation_of_users()) return;
+ break;
+
+ case 2:
+ if (!create_narveos_study()) return;
+ break;
+
+ case 3:
+ if (!create_tripoli_study()) return;
+ break;
+
+ case 4:
+ if (!select_user_by_username()) return;
+ break;
+
+ case 5:
+ if (!select_study_by_state()) return;
+ break;
+
+ case 6:
+ if (!select_study_by_title()) return;
+ break;
+
+ case 7:
+ if (!select_study_by_reference()) return;
+ break;
+
+ case 8:
+ if (!select_study_by_context()) return;
+ break;
+
+ case 9:
+ if (!select_document_by_reference()) return;
+ break;
+
+ case 10:
+ if (!select_knowledge_by_context()) return;
+ break;
+
+ case 11:
+ if (!browse_knowledge()) return;
+ break;
+
+ case 12:
+ if (!read_wordxml_properties()) return;
+ break;
+
+ case 13:
+ if (!read_worddoc_properties()) return;
+ }
+ transax.commit();
+ }
+
+ private static boolean importation_of_users () {
+// ----------------------------------------------
+ try {
+ UserDirectory.importUsers(new File("C:/Users/Daniel/Projets/Internes/SaLoMe/Workspace/org.splat/src/users.xml"));
+
+// Print of imported users
+ List<User> result = UserDirectory.selectAllUsers();
+ for (Iterator<User> i=result.iterator(); i.hasNext();) {
+ User auser = i.next();
+ Role[] role = auser.getRoles();
+ String echo = "Role(s) of user " + auser.getIndex() + " (" + auser.toString() + "): " + role[0].getName();
+ for (int j=1; j<role.length; j++) echo = echo + ", " + role[j].getName();
+ logger.info(echo);
+ }
+ return true;
+ }
+ catch (Exception error) {
+ logger.info("Reason:", error);
+ return false;
+ }
+ }
+
+ private static boolean create_narveos_study () {
+// ----------------------------------------------
+ try {
+
+ User.Properties uprop = new User.Properties();
+ List<User> ulist = UserDirectory.selectUsersWhere(uprop.setOrganizationName("Euriware"));
+ User jb = ulist.get(0); // Manager of the study
+ User pd = ulist.get(1); // Author of specifications
+ User hl = UserDirectory.selectUser("hl"); // Geometry expert
+ User sd = UserDirectory.selectUser("sdd"); // Customer
+
+
+// Creation of the Study object
+ SimpleDateFormat on = new SimpleDateFormat("dd/MM/yyyy");
+ SimpleDateFormat at = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+ Study.Properties sprop = new Study.Properties();
+
+ Date someday = on.parse("25/01/2010");
+ Study mystudy = Database.createStudy(sprop.setTitle("Caractérisation du béton SERCOTER").setDate(someday).setManager(jb)
+ .setDescription("Cette étude est livrée avec l'application comme exemple pour tester les fonctions de recherche et de navigation."));
+
+
+// Addition of the default scenario
+ Scenario.Properties oprop = new Scenario.Properties();
+ Scenario myscenar = mystudy.addScenario(oprop.setTitle("Scénario 1").setDate(someday));
+
+
+// Definition of the project team
+ mystudy.addContributor(pd);
+
+
+// Addition of documents
+ Step[] ownstep = mystudy.getSteps();
+ Step[] nexstep = myscenar.getSteps();
+ Document.Properties dprop;
+ DocumentType request = Document.selectType("requirements");
+ DocumentType spec = Document.selectType("specification");
+ DocumentType geom = Document.selectType("geometry");
+ DocumentType note = Document.selectType("memorandum");
+ DocumentType delivery = Document.selectType("report"); // Final report of the study
+
+// Set of document validation cycles
+ mystudy.setValidationCycle(geom, new ValidationCycle.Properties().setActor(ValidationStep.REVIEW, hl)
+ .setActor(ValidationStep.APPROVAL, jb));
+// (1) Customer requirements
+ dprop = new Document.Properties();
+ Publication cdc = ownstep[0].createDocument(dprop.setName("Proposition technique")
+ .setExternReference("GCVP-P/09-1629/V1")
+ .setDate(on.parse("08/02/2010"))
+ .setType(request)
+ .setFormat("pdf")
+ .setAuthor(sd));
+ logger.info("Uploading file \"" + cdc.getSourceFile().getName() + "\" into " + cdc.value().getSaveDirectory().getPath());
+ cdc.saveAs(ProgressState.EXTERN);
+
+// (2)(3) General specifications based on (using) Customer requirements
+ dprop.clear();
+ Publication specgen = ownstep[0].createDocument(dprop.setName("Spécifications générales")
+ .setDate(on.parse("05/03/2010"))
+ .setType(spec)
+ .setFormat("xml")
+ .setAuthor(pd));
+ logger.info("Uploading file \"" + specgen.getSourceFile().getName() + "\" into " + specgen.value().getSaveDirectory().getPath());
+ specgen.saveAs(ProgressState.inWORK); // Version 0.1
+ specgen.addDependency(cdc);
+
+ dprop.clear();
+ specgen = ownstep[0].versionDocument(specgen, dprop.setDate(on.parse("12/03/2010"))
+ .setDescription("Ajout de la description du scénario de calcul"));
+ specgen.saveAs(ProgressState.inWORK); // Version 0.2
+ specgen.addDependency(cdc);
+
+// (4) Assembly geometry based on (using) General specifications
+ dprop.clear();
+ Publication sercoter = nexstep[1].createDocument(dprop.setName("Assemblage SERCOTER")
+ .setDate(on.parse("26/03/2010"))
+ .setType(geom)
+ .setFormat("sldasm")
+ .setAuthor(jb));
+ logger.info("Uploading file \"" + sercoter.getSourceFile().getName() + "\" into " + sercoter.value().getSaveDirectory().getPath());
+ sercoter.saveAs(ProgressState.inWORK);
+ sercoter.addDependency(specgen);
+
+// (5) Technical note based on (using) General specifications and Assembly geometry
+ dprop.clear();
+ Publication report = nexstep[1].createDocument(dprop.setName("Modifications et simplifications retenues")
+ .setDate(on.parse("26/03/2010"))
+ .setType(note)
+ .setFormat("doc")
+ .setAuthor(jb));
+ logger.info("Uploading file \"" + report.getSourceFile().getName() + "\" into " + report.value().getSaveDirectory().getPath());
+ report.saveAs(ProgressState.inWORK);
+ report.addDependency(specgen);
+ report.addDependency(sercoter);
+ report.promote(on.parse("26/03/2010"));
+
+// (6) New version of General specifications
+ dprop.clear();
+ specgen = ownstep[0].versionDocument(specgen, dprop.setDate(on.parse("24/03/2010"))
+ .setDescription("Prise en compte des retours internes"));
+ specgen.saveAs(ProgressState.inDRAFT); // Version 0.3
+ specgen.addDependency(cdc);
+
+ specgen.review(at.parse("26/03/2010 10:15")); // Promotion to version 1.0
+ specgen.attach("pdf");
+ specgen.approve(at.parse("26/03/2010 16:30")).setComment("Le document peut être envoyé au client.");
+ logger.info("Uploading file \"" + specgen.value().getTitle() + ".pdf\" into " + specgen.value().getSaveDirectory().getPath());
+
+// (7)
+ Publication result = ownstep[1].createDocument(dprop.setName("Comparaison des résultats")
+ .setDate(on.parse("16/04/2010"))
+ .setType(delivery)
+ .setFormat("xml")
+ .setAuthor(jb));
+ logger.info("Uploading file \"" + result.getSourceFile().getName() + "\" into " + result.value().getSaveDirectory().getPath());
+ result.saveAs(ProgressState.inDRAFT); // Promotes the study to In-Draft
+ result.review (at.parse("19/04/2010 10:15")); // Promotes the study to In-Check
+
+
+// Assignment of simulation contexts
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ SimulationContextType customer = SimulationContext.selectType("customer");
+ SimulationContextType product = SimulationContext.selectType("product");
+ SimulationContextType phase = SimulationContext.selectType("phase");
+ SimulationContextType need = SimulationContext.selectType("need");
+ SimulationContextType subject = SimulationContext.selectType("purpose");
+ SimulationContextType physics = SimulationContext.selectType("physic");
+ SimulationContextType object = SimulationContext.selectType("object");
+ SimulationContextType part = SimulationContext.selectType("part");
+ SimulationContextType model = SimulationContext.selectType("model");
+ SimulationContextType element = SimulationContext.selectType("element");
+ SimulationContextType shape = SimulationContext.selectType("shape");
+ SimulationContextType platform = SimulationContext.selectType("platform");
+ SimulationContextType module = SimulationContext.selectType("module");
+ SimulationContextType component = SimulationContext.selectType("component");
+
+ List<SimulationContext> ihave = mystudy.getFirstStep().getSimulationContext(customer);
+ if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
+ else {
+ SimulationContext imported = Database.selectSimulationContext(customer, "CEA Cadarache");
+ if (imported == null) {
+ mystudy.addProjectContext(cprop.setType(customer).setValue("CEA Cadarache").setState(ProgressState.APPROVED));
+ } else {
+ mystudy.addProjectContext(imported); // Previously generated
+ }
+ }
+ ihave = mystudy.getFirstStep().getSimulationContext(product);
+ if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
+ else {
+ SimulationContext imported = Database.selectSimulationContext(product, "Réacteur RAPSODIE");
+ if (imported == null) {
+ mystudy.addProjectContext(cprop.setType(product).setValue("Réacteur RAPSODIE").setState(ProgressState.APPROVED));
+ } else {
+ mystudy.addProjectContext(imported); // Previously generated
+ }
+ }
+ mystudy.addProjectContext(cprop.setType(phase).setValue("Démantèlement").setState(ProgressState.APPROVED));
+ mystudy.addProjectContext(cprop.setType(need).setValue("Caractérisation du béton SERCOTER").setState(ProgressState.APPROVED));
+ mystudy.addProjectContext(cprop.setType(subject).setValue("Valider les résultats d'une précédente étude").setState(ProgressState.APPROVED));
+ mystudy.addProjectContext(cprop.setType(physics).setValue("Transport de particules").setState(ProgressState.APPROVED));
+ nexstep[1].addSimulationContext(cprop.setType(object).setValue("Réacteur nucléaire").setState(ProgressState.APPROVED));
+ nexstep[1].addSimulationContext(cprop.setType(part).setValue("Ensemble Bloc réacteur et Enceinte en béton").setState(ProgressState.APPROVED));
+// nexstep[2].addSimulationContext(cprop.setType(model).setValue("CSG"));
+ nexstep[2].addSimulationContext(cprop.setType(model).setValue("Éléments finis").setState(ProgressState.APPROVED));
+ nexstep[2].addSimulationContext(cprop.setType(element).setValue("Surfacique").setState(ProgressState.APPROVED));
+ nexstep[2].addSimulationContext(cprop.setType(shape).setValue("Triangles").setState(ProgressState.APPROVED));
+ nexstep[4].addSimulationContext(cprop.setType(platform).setValue("NARVEOS V3").setState(ProgressState.APPROVED));
+ nexstep[4].addSimulationContext(cprop.setType(module).setValue("NARMER V2").setState(ProgressState.APPROVED));
+ nexstep[4].addSimulationContext(cprop.setType(component).setValue("VIRTOOLS V5").setState(ProgressState.APPROVED));
+
+// Assignment of a knowledge
+ KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
+ KnowledgeElementType practice = KnowledgeElement.selectType("bestpractice");
+ KnowledgeElementType limit = KnowledgeElement.selectType("limitation");
+ KnowledgeElementType improvment = KnowledgeElement.selectType("improvement");
+ kprop.setType(limit)
+ .setTitle("Format du modèle géométrique")
+ .setValue("Seul le format 3DXML V5 ou antérieur est supporté.")
+// .setState(ProgressState.APPROVED)
+ .setAuthor(jb);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(practice)
+ .setTitle("Compréhension de l'environnement")
+ .setValue("Avoir une compréhension globale du débit de dose en commençant par effectuer une cartographie.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(jb);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(practice)
+ .setTitle("Calage du modèle radiologique")
+ .setValue("A partir de sources à 1 Bq/m<sup>3</sup>, faire évoluer une source à la fois et vérifier l'impact sur les points de calcul pour connaitre l'influence relative des sources.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(jb);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(practice)
+ .setTitle("Calage du modèle radiologique")
+ .setValue("Toujours faire le premier calcul sans built-up.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(jb);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(limit)
+ .setTitle("Effets diffusés indirects")
+ .setValue("L'outil ne tenant pas compte des effets diffusés indirects, faire attention à la géométrie autour des points de calcul.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(jb);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(improvment)
+ .setTitle("Gestion des écrans")
+ .setValue("Mieux gérer les multi-écrans à géométrie cylindrique.")
+ .setState(ProgressState.inCHECK) // Just for testing the approve() function below
+ .setAuthor(jb);
+ KnowledgeElement kelm = myscenar.addKnowledgeElement(kprop);
+
+ kelm.approve();
+
+ mystudy.moveToPublic();
+
+ logger.info("Study \"" + mystudy.getTitle() + "\" successfully created.");
+ return true;
+ }
+ catch (Exception error) {
+ logger.info("Reason:", error);
+ return false;
+ }
+ }
+
+ private static boolean create_tripoli_study () {
+// ----------------------------------------------
+ User plt = UserDirectory.selectUser("sdd");
+ try {
+// Creation of the Study object
+ SimpleDateFormat todate = new SimpleDateFormat("dd/MM/yyyy");
+ Study.Properties sprop = new Study.Properties();
+
+ Date at = todate.parse("03/05/2011");
+ Study mystudy = Database.createStudy(sprop.setTitle("Validation des voies de production de la plate-forme Radioprotection").setDate(at).setManager(plt));
+
+// Addition of scenarios
+ Scenario.Properties oprop = new Scenario.Properties();
+ Scenario myscenar = mystudy.addScenario(oprop.setTitle("Scénario Tripoli").setDate(at));
+ mystudy.addScenario(oprop.setTitle("Scénario MCNP").setDate(at));
+
+// Addition of documents
+ Step[] ownstep = mystudy.getSteps();
+ Step[] nexstep = myscenar.getSteps();
+
+ DocumentType request = Document.selectType("requirements");
+ DocumentType spec = Document.selectType("specification");
+ DocumentType geom = Document.selectType("geometry");
+ DocumentType mesh = Document.selectType("model");
+ DocumentType note = Document.selectType("memorandum");
+ DocumentType delivery = Document.selectType("report"); // Final report of the study
+ Document.Properties dprop;
+
+ dprop = new Document.Properties();
+ Publication cdc = ownstep[0].createDocument(dprop.setName("Cahier des charges")
+ .setDate(todate.parse("03/05/2011"))
+ .setType(request)
+ .setFormat("pdf")
+ .setAuthor(plt));
+ logger.info("Uploading file \"" + cdc.getSourceFile().getName() + "\" into " + cdc.value().getSaveDirectory().getPath());
+ cdc.saveAs(ProgressState.EXTERN);
+
+ dprop = new Document.Properties();
+ Publication sgen = ownstep[0].createDocument(dprop.setName("Spécifications générales")
+ .setDate(todate.parse("03/05/2010"))
+ .setType(spec)
+ .setFormat("xml")
+ .setAuthor(plt));
+ logger.info("Uploading file \"" + sgen.getSourceFile().getName() + "\" into " + sgen.value().getSaveDirectory().getPath());
+ sgen.saveAs(ProgressState.inDRAFT); // Version 0.1
+ sgen.addDependency(cdc);
+
+ dprop = new Document.Properties();
+ Publication pcc = nexstep[1].createDocument(dprop.setName("Assemblage PCC")
+ .setDate(todate.parse("03/05/2011"))
+ .setType(geom)
+ .setFormat("ProE")
+ .setAuthor(plt));
+ Publication doc = nexstep[1].createDocument(dprop.setName("Description de l'assemblage")
+ .setDate(todate.parse("03/05/2011"))
+ .setType(note)
+ .setFormat("doc")
+ .setAuthor(plt));
+ logger.info("Uploading file \"" + pcc.getSourceFile().getName() + "\" into " + pcc.value().getSaveDirectory().getPath());
+ logger.info("Uploading file \"" + doc.getSourceFile().getName() + "\" into " + doc.value().getSaveDirectory().getPath());
+ pcc.saveAs(ProgressState.inDRAFT);
+ doc.saveAs(ProgressState.inCHECK);
+
+ pcc.review(todate.parse("08/05/2011"));
+ pcc.addDependency(sgen);
+ doc.addDependency(sgen);
+ doc.addDependency(pcc);
+
+ pcc.attach("gdml");
+ logger.info("Uploading file \"" + pcc.value().getTitle() + ".gdml\" into " + pcc.value().getSaveDirectory().getPath());
+
+ dprop = new Document.Properties();
+ Publication csg = nexstep[2].createDocument(dprop.setName("PCC")
+ .setDate(todate.parse("03/05/2011"))
+ .setType(mesh)
+ .setFormat("hdf")
+ .setAuthor(plt));
+ logger.info("Uploading file \"" + csg.getSourceFile().getName() + "\" into " + csg.value().getSaveDirectory().getPath());
+ csg.saveAs(ProgressState.inDRAFT);
+
+ csg.addDependency(pcc);
+
+ csg.attach("gdml", "sans void space");
+ csg.attach("tri", "avec void space");
+ csg.attach("pdf");
+ logger.info("Uploading file \"" + csg.value().getTitle() + ".tri\" into " + csg.value().getSaveDirectory().getPath());
+
+ Publication result = ownstep[1].createDocument(dprop.setName("Comparaison des résultats")
+ .setDate(todate.parse("17/05/2011"))
+ .setType(delivery)
+ .setFormat("xml")
+ .setAuthor(plt));
+ logger.info("Uploading file \"" + result.getSourceFile().getName() + "\" into " + result.value().getSaveDirectory().getPath());
+ result.saveAs(ProgressState.inWORK); // Version 0.1
+ result.promote(todate.parse("18/05/2011")); // Promotes also the study
+
+// Assignment of simulation contexts
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ SimulationContextType customer = SimulationContext.selectType("customer");
+ SimulationContextType product = SimulationContext.selectType("product");
+ SimulationContextType phase = SimulationContext.selectType("phase");
+ SimulationContextType need = SimulationContext.selectType("need");
+ SimulationContextType subject = SimulationContext.selectType("purpose");
+ SimulationContextType physics = SimulationContext.selectType("physic");
+ SimulationContextType object = SimulationContext.selectType("object");
+ SimulationContextType part = SimulationContext.selectType("part");
+ SimulationContextType model = SimulationContext.selectType("model");
+ SimulationContextType element = SimulationContext.selectType("element");
+ SimulationContextType shape = SimulationContext.selectType("shape");
+ SimulationContextType platform = SimulationContext.selectType("platform");
+ SimulationContextType module = SimulationContext.selectType("module");
+
+ List<SimulationContext> ihave = mystudy.getFirstStep().getSimulationContext(customer);
+ if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
+ else {
+ SimulationContext imported = Database.selectSimulationContext(customer, "Fonction transverse sûreté");
+ if (imported == null) {
+ mystudy.addProjectContext(cprop.setType(customer).setValue("Fonction transverse sûreté").setState(ProgressState.APPROVED));
+ } else {
+ mystudy.addProjectContext(imported); // Not generated from specifications
+ }
+ }
+ ihave = mystudy.getFirstStep().getSimulationContext(product);
+ if (ihave.size() > 0) ihave.get(0).approve(); // Generated from specifications
+ else {
+ SimulationContext imported = Database.selectSimulationContext(product, "Laser Mégajoule");
+ if (imported == null) {
+ mystudy.addProjectContext(cprop.setType(product).setValue("Laser Mégajoule").setState(ProgressState.APPROVED));
+ } else {
+ mystudy.addProjectContext(imported); // Not generated from specifications
+ }
+ }
+ mystudy.addProjectContext(cprop.setType(phase).setValue("Dossier de Validation DSGA/SSPP").setState(ProgressState.APPROVED));
+ mystudy.addProjectContext(cprop.setType(need).setValue("Validation du calcul TRIPOLI4.5 via le PlugIn Pro/E").setState(ProgressState.APPROVED));
+ mystudy.addProjectContext(cprop.setType(subject).setValue("Cartographie neutronique").setState(ProgressState.APPROVED));
+ mystudy.addProjectContext(Database.selectSimulationContext(physics, "Transport de particules"));
+ nexstep[1].addSimulationContext(cprop.setType(object).setValue("Bâtiment LMJ").setState(ProgressState.APPROVED));
+ nexstep[1].addSimulationContext(cprop.setType(part).setValue("Bât. Nord, Sud, Hall d'expériences, Hall lasers").setState(ProgressState.APPROVED));
+ nexstep[2].addSimulationContext(cprop.setType(model).setValue("CSG").setState(ProgressState.APPROVED));
+ nexstep[2].addSimulationContext(cprop.setType(element).setValue("Monte Carlo ").setState(ProgressState.APPROVED));
+ nexstep[2].addSimulationContext(cprop.setType(shape).setValue("Combinatoire volumique").setState(ProgressState.APPROVED));
+ nexstep[4].addSimulationContext(cprop.setType(platform).setValue("SALOME-TRIPOLI V2.04").setState(ProgressState.APPROVED));
+ nexstep[4].addSimulationContext(cprop.setType(module).setValue("TRIPOLI4.5").setState(ProgressState.APPROVED));
+
+// Assignment of a knowledge
+ KnowledgeElement.Properties kprop = new KnowledgeElement.Properties();
+ KnowledgeElementType practice = KnowledgeElement.selectType("bestpractice");
+ KnowledgeElementType limit = KnowledgeElement.selectType("limitation");
+ KnowledgeElementType improvment = KnowledgeElement.selectType("improvement");
+ kprop.setType(practice)
+ .setTitle("Compréhension des modèles CAO")
+ .setValue("Convertir le modèle CAO par élément (part) et constituer les assemblages sous GDML en vérifiant à chaque étape qu'il n'existe pas d'intersection entre les éléments.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(plt);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(practice)
+ .setTitle("Génération du volume complémentaire")
+ .setValue("Appliquer la génération du volume complémentaire au modèle GDML global de l'installation en sauvegardant le découpage de l'espace complémentaire en tant que volume.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(plt);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(limit)
+ .setTitle("Découpage du volume complémentaire")
+ .setValue("Inutile de découper le complémentaire pour le code TRIPOLI4.5. Les performances calculs ne sont pas meilleures.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(plt);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(limit)
+ .setTitle("Option de pondération")
+ .setValue("impossible de visualiser sous le viewer OCC les grilles de pondération dans la géométrie (temps d'affichage prohibitif).")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(plt);
+ myscenar.addKnowledgeElement(kprop);
+ kprop.setType(improvment)
+ .setTitle("Grille de pondération TRIPOLI4.5")
+ .setValue("Faire évoluer le viewer Ray tracing pour qu'il puisse afficher les grilles de pondération et de maillage.")
+ .setState(ProgressState.APPROVED)
+ .setAuthor(plt);
+ myscenar.addKnowledgeElement(kprop);
+
+ mystudy.moveToPublic();
+
+ logger.info("Study \"" + mystudy.getTitle() + "\" successfully created.");
+ return true;
+ }
+ catch (Exception error) {
+ logger.info("Reason:", error);
+ return false;
+ }
+ }
+
+ private static boolean select_user_by_username () {
+// -------------------------------------------------
+ String jbt = "jbt";
+ try {
+ User user = UserDirectory.selectUser(jbt);
+ if (user == null) {
+ logger.info("User " + jbt + " not found.");
+ } else {
+ logger.info("User " + jbt + " found:");
+ logger.info("* " + user.getDisplayName() + ", role \"" + user.getRoleNames() + "\"");
+ }
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean select_study_by_state () {
+// -----------------------------------------------
+ String dbc = "jbt";
+ User user = UserDirectory.selectUser(dbc);
+ try {
+ Study.Properties criter1 = new Study.Properties().setState(ProgressState.inPROGRESS);
+ Study.Properties criter2 = new Study.Properties().setState(ProgressState.inWORK).setManager(user);
+ List<Proxy> result = Database.selectStudiesWhere(criter1, criter2);
+ if (result.size() == 0) {
+ logger.info("No study found.");
+ } else {
+ logger.info("Study(ies) found:");
+ for (int i=0; i<result.size(); i++) {
+ logger.info("* \"" + result.get(i).getTitle() + "\"");
+ }
+ }
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean select_study_by_title () {
+// -----------------------------------------------
+ String words = "sercoter";
+ try {
+ Study.Properties criteria = new Study.Properties();
+ List<Proxy> result = Database.selectStudiesWhere(criteria.setTitle(words));
+ if (result.size() == 0) {
+ logger.info("No study found with a title including \"" + words + "\".");
+ } else {
+ logger.info("Study(ies) found:");
+ for (int i=0; i<result.size(); i++) {
+ logger.info("* \"" + result.get(i).getTitle() + "\"");
+ }
+ }
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean select_study_by_reference () {
+// ---------------------------------------------------
+ String refid = "PLM110001";
+ try {
+ Study study = Database.selectStudy(refid);
+ if (study == null) {
+ logger.info("Study " + refid + " not found.");
+ return false;
+ } else {
+ logger.info("Study " + refid + ": " + study.getTitle() + ".");
+ display_study(study);
+ return true;
+ }
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean select_study_by_context () {
+// -------------------------------------------------
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ SimulationContextType ctype = SimulationContext.selectType("Produit");
+ List<SimulationContext> context = Database.selectSimulationContextsWhere(cprop.setType(ctype));
+ for (Iterator<SimulationContext> i=context.iterator(); i.hasNext();) {
+ SimulationContext reactor = i.next();
+ if (reactor.getValue().equals("Réacteur RAPSODIE")) {
+
+ context = new Vector<SimulationContext>();
+ context.add(reactor);
+
+ Study.Properties sprop = new Study.Properties();
+ List<Proxy> result = Database.selectStudiesWhere(sprop.setSimulationContexts(context)
+ .setState(ProgressState.inPROGRESS));
+ if (result.size() == 0) {
+ logger.info("Study on Réacteur RAPSODIE not found.");
+ return false;
+ } else {
+ logger.info("Study on Réacteur RAPSODIE: " + result.get(0).getTitle() + ".");
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean select_document_by_reference () {
+// ------------------------------------------------------
+ String refid = "PLM100001.02";
+ String verid = "2.0.0";
+ try {
+ Document result = Database.selectDocument(refid, verid);
+ String title = result.getTitle();
+ String refdoc = result.getReference();
+ logger.info("Document " + refdoc + ": " + title + ".");
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean select_knowledge_by_context () {
+// -------------------------------------------------
+ SimulationContext.Properties cprop = new SimulationContext.Properties();
+ SimulationContextType ctype = SimulationContext.selectType("Produit");
+ List<SimulationContext> context = Database.selectSimulationContextsWhere(cprop.setType(ctype));
+ for (Iterator<SimulationContext> i=context.iterator(); i.hasNext();) {
+ SimulationContext reactor = i.next();
+ if (reactor.getValue().equals("Réacteur RAPSODIE")) {
+
+ context = new Vector<SimulationContext>();
+ context.add(reactor);
+
+ KnowledgeElementType ktype = KnowledgeElement.selectType("Bonne pratique");
+ KnowledgeElement.Properties sprop = new KnowledgeElement.Properties();
+ List<Proxy> result = Database.selectKnowledgeElementsWhere(sprop.setSimulationContexts(context)
+ .setType(ktype));
+ if (result.size() == 0) {
+ logger.info("Study on Réacteur RAPSODIE not found.");
+ return false;
+ } else {
+ logger.info("Study on Réacteur RAPSODIE: " + result.get(0).getTitle() + ".");
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean display_study (Study study) {
+// --------------------------------------------------
+ try {
+ Step[] mystep = study.getSteps();
+ Scenario[] branch = study.getScenarii();
+ List<Publication> list;
+
+ for (int j=0; j<mystep.length; j++) {
+ Step step = mystep[j];
+ list = step.getAllDocuments();
+ if (list.size() == 0) continue;
+ logger.info("Step 0." + j + ":");
+ for (Iterator<Publication> k=list.iterator(); k.hasNext();) {
+ Publication doc = k.next();
+ String output = "* " + doc.value().getTitle();
+ List<Publication> exports = doc.getRelations(ConvertsRelation.class);
+ if (exports.size() > 0) {
+ output = output + " et export(s)";
+ for (Iterator<Publication> m=exports.iterator(); m.hasNext(); ) {
+ output = output + " " + m.next().getSourceFile().getName();
+ }
+ }
+ logger.info(output);
+ }
+ }
+ for (int i=0; i<branch.length; i++) {
+ Scenario scene = branch[i];
+ mystep = scene.getSteps();
+ for (int j=0; j<mystep.length; j++) {
+ Step step = mystep[j];
+ list = step.getAllDocuments();
+ if (list.size() == 0) continue;
+ logger.info("Step " + (i+1) + "." + j + ":");
+ for (Iterator<Publication> k=list.iterator(); k.hasNext();) {
+ Publication doc = k.next();
+ String output = "* " + doc.value().getTitle();
+ List<Publication> exports = doc.getRelations(ConvertsRelation.class);
+ if (exports.size() > 0) {
+ output = output + " et export(s)";
+ for (Iterator<Publication> m=exports.iterator(); m.hasNext(); ) {
+ output = output + " " + m.next().getSourceFile().getName();
+ }
+ }
+ logger.info(output);
+ }
+ }
+ }
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean browse_knowledge () {
+// ------------------------------------------
+ try {
+ Study study = Database.selectStudy(1);
+ Scenario[] branch = study.getScenarii();
+ List<KnowledgeElementType> types = KnowledgeElement.selectTypesWhere(ProgressState.APPROVED);
+
+ for (int i=0; i<branch.length; i++) {
+ Scenario scene = branch[i];
+ List<KnowledgeElement> kelms = scene.getAllKnowledgeElements();
+ Iterator<KnowledgeElement> more = kelms.iterator();
+ KnowledgeElement next = null;
+ if (more.hasNext()) next = more.next();
+
+ for (Iterator<KnowledgeElementType> j=types.iterator(); j.hasNext();) {
+ KnowledgeElementType type = j.next();
+ logger.info(type.getName() + ":");
+ while (next != null && next.getType().equals(type)) {
+ logger.info("* " + next.getTitle() + ": " + next.getValue());
+ }
+ }
+ }
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean read_wordxml_properties () {
+// -------------------------------------------------
+ File template = new File("D:/Atelier/Eclipse/salome/org.splat/src/template.xml");
+ File copy = new File("D:/Atelier/Eclipse/salome/org.splat/src/example.xml");
+ try {
+ if (copy.exists()) copy.delete();
+ Do.copy(template, copy);
+ Writer credoc = Toolbox.getWriter(copy);
+ if (credoc != null) {
+
+// Setting of properties
+ credoc.updateProperty("customer", "CEA Cadarache");
+ credoc.updateProperty("title", "Spécifications générales");
+ credoc.save();
+
+// Displaying properties
+ Reader example = Toolbox.getReader(copy);
+ Revision.Format convert = new Revision.Format("V%M.%m");
+ String value;
+ logger.info("Properties of \"" + copy.getName() + "\" document:");
+
+ value = example.extractProperty("title");
+ logger.info("* Title = " + value);
+ value = example.extractProperty("version");
+ Revision verdoc = convert.parse(value);
+ logger.info("* Version = " + verdoc.toString());
+ value = example.extractProperty("customer");
+ logger.info("* Customer = " + value);
+ value = example.extractText();
+ logger.info("* Text = " + value);
+ }
+ return false;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean read_worddoc_properties () {
+// -------------------------------------------------
+ File file = new File("D:/Atelier/Eclipse/salome/org.splat/src/example.docx");
+ try {
+ if (!file.exists()) return false;
+
+ Reader example = Toolbox.getReader(file);
+ logger.info("Properties of \"" + file.getName() + "\" document:");
+ String value;
+
+ value = example.extractProperty("customer");
+ logger.info("* Customer = " + value);
+ value = example.extractProperty("title");
+ logger.info("* Title = " + value);
+ value = example.extractText();
+ logger.info("* Text = " + value);
+ return false;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<users>
+
+<user>
+ <first>Jean-Bernard</first>
+ <last>Trépon</last>
+ <display>Jean-Bernard Trépon</display>
+ <username>jbt</username>
+ <role>manager</role>
+ <mail>jean-bernard.trepon@euriware.fr</mail>
+ <organization>Euriware</organization>
+</user>
+
+<user>
+ <first>Hervé</first>
+ <last>Lexpert</last>
+ <display>Hervé</display>
+ <username>hl</username>
+ <role>manager</role>
+ <mail>herve.lexpert@opencascade.com</mail>
+ <organization>OC-F</organization>
+</user>
+
+<user>
+ <first>Paul</first>
+ <last>Durand</last>
+ <username>pdd</username>
+ <role>studengineer</role>
+ <mail>paul.durand@euriware.fr</mail>
+ <organization>Euriware</organization>
+</user>
+
+<user>
+ <first>Sylvie</first>
+ <last>Dupond</last>
+ <username>sdd</username>
+ <role>manager</role>
+ <mail>sylvie.dupond@cea.fr</mail>
+ <organization>CEA</organization>
+</user>
+
+<user>
+ <first>Michel</first>
+ <last>Karyo</last>
+ <username>mko</username>
+ <password>mko</password>
+ <role>manager</role>
+ <mail>michel.karyo@opencascade.com</mail>
+ <organization>Nx1</organization>
+</user>
+
+<user>
+ <first>Pierre</first>
+ <last>Jarnet</last>
+ <username>pjt</username>
+ <password>pjt</password>
+ <role>manager</role>
+ <mail>pierre.jarnet@euriware.fr</mail>
+ <organization>Nx2</organization>
+</user>
+
+</users>
\ No newline at end of file
function initialize (result) {
// ----------------------------
- var refon = search.owner[3].checked;
- if (refon) {
- var contx = document.getElementById("contlist");
- var words = document.getElementById("wordin");
- contx.style.display = "none";
- words.style.display = "none";
- } else {
- var refin = document.getElementById("refid");
- refin.style.display = "none";
+ var state = search.state.value;
+
+ if (state == "inWORK" || state == "inDRAFT" || state == "inCHECK") {
+ search.visibility[0].checked = true;
+ search.visibility[1].disabled = true;
+ search.visibility[2].disabled = true;
}
- search.state.disabled = !search.owner[0].checked;
- search.author.disabled = !search.owner[1].checked;
- if (search.owner[0].checked && search.state.value == "0") result = "obsolete";
- if (search.owner[1].checked && search.author.value == "0") result = "obsolete";
if (result == "obsolete") changeFilter(); // Hides the result section and enables the Search button
}
+ function setState () {
+// --------------------
+ var state = search.state.value;
+
+ if (state == "inWORK" || state == "inDRAFT" || state == "inCHECK") {
+ search.visibility[0].checked = true;
+ search.visibility[1].disabled = true;
+ search.visibility[2].disabled = true;
+ } else if (search.visibility[1].value != "onlypublic") {
+ search.visibility[1].disabled = false;
+ search.visibility[2].disabled = false;
+ }
+ changeFilter();
+ }
+
function changeFilter () {
// ------------------------
var result = document.getElementById("resulist");
search.elements[0].value = "0"; // Marks the result obsolete
result.style.display = "none"; // Hides the result section
search.refresh.disabled = false; // Enables the Search button
- if (search.owner[0].checked) {
- if (search.state.value == "0") search.refresh.disabled = true;
- } else search.state.value = "0";
- if (search.owner[1].checked) {
- if (search.author.value == "0") search.refresh.disabled = true;
- } else search.author.value = "0";
- }
-
- function setReference () {
-// ------------------------
- var result = document.getElementById("resulist");
- var refin = document.getElementById("refid");
- var words = document.getElementById("wordin");
- var contx = document.getElementById("contlist");
-
- result.style.display = "none";
- words.style.display = "none";
- contx.style.display = "none";
- refin.style.display = "block";
- search.elements[4].focus();
- search.refresh.disabled = false;
- }
-
- function unsetReference () {
-// ------------------------
- var result = document.getElementById("resulist");
- var refin = document.getElementById("refid");
- var words = document.getElementById("wordin");
- var contx = document.getElementById("contlist");
-
- result.style.display = "none";
- refin.style.display = "none";
- words.style.display = "block";
- contx.style.display = "block";
- search.refresh.disabled = false;
- search.state.disabled = !search.owner[0].checked;
- search.author.disabled = !search.owner[1].checked;
- if (search.owner[0].checked && search.state.value == "0") search.refresh.disabled = true;
- if (search.owner[1].checked && search.author.value == "0") search.refresh.disabled = true;
}
function removeContext (index) {
%>
<%@ page import="org.splat.som.KnowledgeElement"%>
<%@ page import="org.splat.som.ApplicationRights"%>
+<%@ page import="org.splat.simer.ApplicationSettings"%>
+<%@ page import="java.util.ResourceBundle"%>
+<%@ page import="java.util.Calendar"%>
+<%@ page import="java.text.SimpleDateFormat"%>
<%@
taglib prefix="s" uri="/struts-tags"
%>
-->
<% String action = request.getParameter("action");
- ApplicationRights user = (ApplicationRights)session.getAttribute("user.rights");
+ ApplicationRights rights = (ApplicationRights)session.getAttribute("user.rights");
+ ResourceBundle locale = ResourceBundle.getBundle("som", ApplicationSettings.getCurrentLocale());
+ String format = locale.getString("date.format");
+ SimpleDateFormat tostring = new SimpleDateFormat(format);
String result = "uptodate";
- boolean anonymous = true;
+ boolean connected = false;
- if (user.canCreateStudy()) anonymous = false;
+ if (rights.getUser() != null) connected = true;
if (session.getAttribute("search.result") == null) result = "obsolete";
%>
<s:set var="todo"><%=action%></s:set>
+<s:set var="user"><%=connected%></s:set>
+<s:set var="format"><%=format%></s:set>
+<s:set var="today"><%=tostring.format(java.util.Calendar.getInstance().getTime())%></s:set>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<!-- Search criteria section
=============================================================================================================================
-->
- <div id="tab-bar">
- <jsp:include page="/jsp/searchtabs.jsp"/>
- </div>
<div id=article-box>
- <div id="top-spacer"></div>
+ <div id=section><s:text name="title.criteria"/></div>
<div id="article-body">
<form name="search" action="refresh-knowledge" method="post">
<input type=hidden name="contextIndex" />
- <s:set var="valid"><s:text name="button.result"/></s:set>
+ <s:set var="match1" value="criteriaMatch"/>
+ <s:set var="match2" value="contextMatch"/>
+ <s:set var="type" value="state"/>
+ <s:set var="him" value="author"/>
<table width=100% cellpadding=0 cellspacing=0 border=0 class=text>
<tr height=20>
- <td width=40%> <s:text name="field.among"/></td>
- <td width=60%> <s:text name="field.context"/></td>
- </tr>
- <tr height=1 bgcolor=#AAAAAA><td colspan=3></td></tr>
- <tr valign=top>
- <td>
- <div id="article-item">
- <s:if test="owner == 'all'">
- <input type=radio name="owner" value="all" checked onClick="unsetReference()"><s:text name="criterion.knowledge.all"/>
+ <td width=40%>
+ <b><s:text name="field.among"/></b>
+ <s:if test="%{#match1 == 'all'}">
+ <input type=radio name="criteriaMatch" value="all" checked onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="criteriaMatch" value="any" onClick="changeFilter()"><s:text name="field.matchany"/>
+ </s:if><s:else>
+ <input type=radio name="criteriaMatch" value="all" onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="criteriaMatch" value="any" checked onClick="changeFilter()"><s:text name="field.matchany"/>
+ </s:else>
+ </td>
+ <td width=60%>|
+ <b><s:text name="field.context"/></b>
+ <s:if test="%{#match2 == 'all'}">
+ <input type=radio name="contextMatch" value="all" checked onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="contextMatch" value="any" onClick="changeFilter()"><s:text name="field.matchany"/>
</s:if><s:else>
- <input type=radio name="owner" value="all" onClick="unsetReference()"><s:text name="criterion.knowledge.all"/>
+ <input type=radio name="contextMatch" value="all" onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="contextMatch" value="any" checked onClick="changeFilter()"><s:text name="field.matchany"/>
</s:else>
- <s:set var="type" value="state"/>
- <select name="state" style="width: <s:text name="size.knowledge.state"/>" onChange="changeFilter()">
- <option value="0"><s:text name="menu.select" /></option>
+ </td>
+ </tr>
+ <tr height=1 bgcolor=#AAAAAA><td colspan=2></td></tr>
+ </table>
+
+ <table width=100% cellpadding=0 cellspacing=0 border=0 class=text>
+ <tr valign=top>
+ <td width=40%>
+ <table cellpadding=0 cellspacing=0 border=0 class=text>
+ <tr>
+ <td colspan=2><s:text name="criterion.knowledge"/> </td>
+ <td colspan=3 align=center>
+ <select name="state" style="width: <s:text name="size.search.select"/>" onChange="changeFilter()">
<s:iterator value="knowledgeTypes">
<s:if test="%{index == #type}">
- <option value="<s:property value="index"/>" selected> <s:text name="type.knowledge.%{name}" /></option>
+ <option value="<s:property value="index"/>" selected><s:text name="type.knowledge.%{name}" /></option>
</s:if><s:else>
- <option value="<s:property value="index"/>"> <s:text name="type.knowledge.%{name}" /></option>
+ <option value="<s:property value="index"/>"><s:text name="type.knowledge.%{name}" /></option>
</s:else>
</s:iterator>
</select>
- </div>
- <div id="article-item">
- <s:if test="owner == 'his'">
- <input type=radio name="owner" value="his" checked onClick="unsetReference()"><s:text name="criterion.knowledge.his"/>
- </s:if><s:else>
- <input type=radio name="owner" value="his" onClick="unsetReference()"><s:text name="criterion.knowledge.his"/>
- </s:else>
- <s:set var="him" value="author"/>
- <select name="author" style="width: <s:text name="size.knowledge.author"/>" onChange="changeFilter()">
- <option value="0"><s:text name="menu.select" /></option>
+ </td>
+ </tr>
+ <tr>
+ <td colspan=5 align=left>
+ <s:if test="visibility == 'PRIVATE'">
+ <input type=radio name="visibility" value="PRIVATE" checked onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="PUBLIC" onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" onClick="changeFilter()"><s:text name="field.either"/>
+ </s:if>
+ <s:elseif test="visibility == 'PUBLIC'">
+ <input type=radio name="visibility" value="PRIVATE" onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="PUBLIC" checked onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" onClick="changeFilter()"><s:text name="field.either"/>
+ </s:elseif>
+ <s:elseif test="visibility == 'onlypublic'">
+ <input type=radio name="visibility" value="PRIVATE" disabled onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="onlypublic" checked onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" disabled onClick="changeFilter()"><s:text name="field.either"/>
+ </s:elseif>
+ <s:else>
+ <input type=radio name="visibility" value="PRIVATE" onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="PUBLIC" onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" checked onClick="changeFilter()"><s:text name="field.either"/>
+ </s:else>
+ </td>
+ </tr>
+ <tr>
+ <td colspan=2><s:text name="criterion.author"/> </td>
+ <td colspan=3 align=center>
+ <select name="author" style="width: <s:text name="size.search.select"/>" onChange="changeFilter()">
+ <option value="0"><s:text name="criterion.anybody" /></option>
<s:iterator value="candidates">
<s:if test="%{index == #him}">
<option value="<s:property value="index"/>" selected><s:property value="toString()"/></option>
</s:else>
</s:iterator>
</select>
- </div>
- <div id="article-item">
-<% if (anonymous) {
-%> <input type=radio name="owner" value="mine" disabled><font color="#A1A192"><s:text name="criterion.knowledge.mine"/></font>
-<% } else {
-%> <s:if test="owner == 'mine'">
- <input type=radio name="owner" value="mine" checked onClick="unsetReference()"><s:text name="criterion.knowledge.mine"/>
- </s:if><s:else>
- <input type=radio name="owner" value="mine" onClick="unsetReference()"><s:text name="criterion.knowledge.mine"/>
- </s:else>
-<% } %> </div>
- <div id="article-item">
- <s:if test="owner == 'ref'">
- <input type=radio name="owner" value="ref" checked onClick="setReference()"><s:text name="criterion.knowledge.ref"/>
- </s:if><s:else>
- <input type=radio name="owner" value="ref" onClick="setReference()"><s:text name="criterion.knowledge.ref"/>
- </s:else>
- <div id=refid>
- <input type=text name="reference" value="<s:property value="%{reference}"/>" size="18" onKeydown="changeFilter()"/>
- </div>
- </div>
+ </td>
+ </tr>
+ <tr>
+ <s:set var="tipdate">
+ <s:text name="help.search.date">
+ <s:param><s:text name="%{#format}"/></s:param>
+ <s:param><s:text name="%{#today}"/></s:param>
+ </s:text>
+ </s:set>
+ <td><s:text name="field.credate"/> </td>
+ <td><s:text name="field.after"/> </td>
+ <td><input type=text name=after size=7 onKeydown="changeFilter()" title="<s:property value="%{#tipdate}"/>" /> </td>
+ <td><s:text name="field.before"/> </td>
+ <td><input type=text name=before size=7 onKeydown="changeFilter()" title="<s:property value="%{#tipdate}"/>" /></td>
+ </tr>
+ <tr height=26><td></td></tr>
+ </table>
+ <table cellpadding=0 cellspacing=0 border=0 class=text>
+ <tr>
+ <td><s:text name="field.contain"/>: </td>
+ <td><input type=text name=words style="width: <s:text name="size.search.input"/>" value="<s:property value="%{words}"/>" onKeydown="changeFilter()" title="<s:text name="help.search.title"/>" /></td>
+ </tr><tr>
+ <td><s:text name="field.reference"/>: </td>
+ <td><input type=text name="reference" style="width: <s:text name="size.search.input"/>" value="<s:property value="%{reference}"/>" onKeydown="changeFilter()" title="<s:text name="help.search.refid"/>" /></td>
+ </tr>
+ </table>
</td>
- <td rowspan=2>
- <div id=contlist>
-
+ <td width=60%>
<table cellpadding=0 cellspacing=0 border=0 class=text>
<s:iterator value="simulationContexts">
<tr>
</s:iterator>
</select>
</s:if>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <div id=wordin>
- <br/><s:text name="field.contain"/> : <input type=text name=words value="<s:property value="%{words}"/>" onKeydown="changeFilter()" />
- </div>
</td>
</tr>
+ </table>
+
+ <table width=100% cellpadding=0 cellspacing=0 border=0 class=text>
<tr>
- <td></td>
- <td align=left>
- <input type="submit" name="refresh" value="<s:text name="button.result"/>" disabled/>
- </td>
+ <td width=40%></td>
+ <td width=60% align=left><input type="submit" name="refresh" value="<s:text name="button.result"/>" disabled/></td>
</tr>
</table>
%>
<%@ page import="org.splat.som.Study"%>
<%@ page import="org.splat.som.ApplicationRights"%>
+<%@ page import="org.splat.simer.ApplicationSettings"%>
+<%@ page import="java.util.ResourceBundle"%>
+<%@ page import="java.util.Calendar"%>
+<%@ page import="java.text.SimpleDateFormat"%>
<%@
taglib prefix="s" uri="/struts-tags"
%>
-->
<% String action = request.getParameter("action");
- ApplicationRights user = (ApplicationRights)session.getAttribute("user.rights");
+ ApplicationRights rights = (ApplicationRights)session.getAttribute("user.rights");
+ ResourceBundle locale = ResourceBundle.getBundle("som", ApplicationSettings.getCurrentLocale());
+ String format = locale.getString("date.format");
+ SimpleDateFormat tostring = new SimpleDateFormat(format);
String result = "uptodate";
- boolean anonymous = true;
+ boolean connected = false;
- if (user.canCreateStudy()) anonymous = false;
+ if (rights.getUser() != null) connected = true;
if (session.getAttribute("search.result") == null) result = "obsolete";
%>
<s:set var="todo"><%=action%></s:set>
+<s:set var="user"><%=connected%></s:set>
+<s:set var="format"><%=format%></s:set>
+<s:set var="today"><%=tostring.format(java.util.Calendar.getInstance().getTime())%></s:set>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<!-- Search criteria section
=============================================================================================================================
-->
- <div id="tab-bar">
- <jsp:include page="/jsp/searchtabs.jsp"/>
- </div>
<div id=article-box>
- <div id="top-spacer"></div>
+ <div id=section><s:text name="title.criteria"/></div>
<div id="article-body">
<form name="search" action="refresh-study" method="post">
<input type=hidden name="contextIndex" />
- <s:set var="valid"><s:text name="button.result"/></s:set>
+ <s:set var="match1" value="criteriaMatch"/>
+ <s:set var="match2" value="contextMatch"/>
+ <s:set var="him" value="author"/>
<table width=100% cellpadding=0 cellspacing=0 border=0 class=text>
<tr height=20>
- <td width=40%> <s:text name="field.among"/></td>
- <td width=60%> <s:text name="field.context"/></td>
- </tr>
- <tr height=1 bgcolor=#AAAAAA><td colspan=3></td></tr>
- <tr valign=top>
- <td>
- <div id="article-item">
- <s:if test="owner == 'all'">
- <input type=radio name="owner" value="all" checked onClick="unsetReference()"><s:text name="criterion.study.all"/>
+ <td width=40%>
+ <b><s:text name="field.among"/></b>
+ <s:if test="%{#match1 == 'all'}">
+ <input type=radio name="criteriaMatch" value="all" checked onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="criteriaMatch" value="any" onClick="changeFilter()"><s:text name="field.matchany"/>
</s:if><s:else>
- <input type=radio name="owner" value="all" onClick="unsetReference()"><s:text name="criterion.study.all"/>
+ <input type=radio name="criteriaMatch" value="all" onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="criteriaMatch" value="any" checked onClick="changeFilter()"><s:text name="field.matchany"/>
</s:else>
- <select name="state" style="width: <s:text name="size.study.state"/>" onChange="changeFilter()">
- <option value="0"><s:text name="menu.select" /></option>
- <s:if test="area == 'reference'">
- <s:if test="state == 'ARCHIVED'"> <option value="ARCHIVED" selected><s:text name="criterion.archived" /></option></s:if>
- <s:else> <option value="ARCHIVED" ><s:text name="criterion.archived" /></option></s:else>
- <s:if test="state == 'TEMPLATE'"> <option value="TEMPLATE" selected><s:text name="criterion.template" /></option></s:if>
- <s:else> <option value="TEMPLATE" ><s:text name="criterion.template" /></option></s:else>
- </s:if><s:else>
- <s:if test="state == 'inPROGRESS'"><option value="inPROGRESS" selected><s:text name="criterion.inprogress" /></option></s:if>
- <s:else> <option value="inPROGRESS" ><s:text name="criterion.inprogress" /></option></s:else>
- <s:if test="state == 'inDRAFT'"> <option value="inDRAFT" selected><s:text name="criterion.indraft" /></option></s:if>
- <s:else> <option value="inDRAFT" ><s:text name="criterion.indraft" /></option></s:else>
- <s:if test="state == 'inCHECK'"> <option value="inCHECK" selected><s:text name="criterion.incheck" /></option></s:if>
- <s:else> <option value="inCHECK" ><s:text name="criterion.incheck" /></option></s:else>
- <s:if test="state == 'APPROVED'"> <option value="APPROVED" selected><s:text name="criterion.approved" /></option></s:if>
- <s:else> <option value="APPROVED" ><s:text name="criterion.approved" /></option></s:else>
- </s:else>
- </select>
- </div>
- <div id="article-item">
- <s:if test="owner == 'his'">
- <input type=radio name="owner" value="his" checked onClick="unsetReference()"><s:text name="criterion.study.his"/>
+ </td>
+ <td width=60%>|
+ <b><s:text name="field.context"/></b>
+ <s:if test="%{#match2 == 'all'}">
+ <input type=radio name="contextMatch" value="all" checked onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="contextMatch" value="any" onClick="changeFilter()"><s:text name="field.matchany"/>
</s:if><s:else>
- <input type=radio name="owner" value="his" onClick="unsetReference()"><s:text name="criterion.study.his"/>
+ <input type=radio name="contextMatch" value="all" onClick="changeFilter()"><s:text name="field.matchall"/>
+
+ <input type=radio name="contextMatch" value="any" checked onClick="changeFilter()"><s:text name="field.matchany"/>
</s:else>
- <s:set var="him" value="author"/>
- <select name="author" style="width: <s:text name="size.study.author"/>" onChange="changeFilter()">
- <option value="0"><s:text name="menu.select" /></option>
+ </td>
+ </tr>
+ <tr height=1 bgcolor=#AAAAAA><td colspan=2></td></tr>
+ </table>
+
+ <table width=100% cellpadding=0 cellspacing=0 border=0 class=text>
+ <tr valign=top>
+ <td width=40%>
+ <table cellpadding=0 cellspacing=0 border=0 class=text>
+ <tr>
+ <td colspan=2><s:text name="criterion.study"/> </td>
+ <td colspan=3 align=center>
+ <select name="state" style="width: <s:text name="size.search.select"/>" onChange="setState()">
+ <s:if test="state == 'ANY'"> <option value="ANY" selected><s:text name="criterion.any" /></option></s:if>
+ <s:else> <option value="ANY" ><s:text name="criterion.any" /></option></s:else>
+ <s:if test="#user">
+ <s:if test="state == 'inWORK'"> <option value="inWORK" selected><s:text name="criterion.inwork" /></option></s:if>
+ <s:else> <option value="inWORK" ><s:text name="criterion.inwork" /></option></s:else>
+ <s:if test="state == 'inDRAFT'"> <option value="inDRAFT" selected><s:text name="criterion.indraft" /></option></s:if>
+ <s:else> <option value="inDRAFT" ><s:text name="criterion.indraft" /></option></s:else>
+ <s:if test="state == 'inCHECK'"> <option value="inCHECK" selected><s:text name="criterion.incheck" /></option></s:if>
+ <s:else> <option value="inCHECK" ><s:text name="criterion.incheck" /></option></s:else>
+ </s:if>
+ <s:if test="state == 'APPROVED'"> <option value="APPROVED" selected><s:text name="criterion.approved" /></option></s:if>
+ <s:else> <option value="APPROVED" ><s:text name="criterion.approved" /></option></s:else>
+ <s:if test="state == 'TEMPLATE'"> <option value="TEMPLATE" selected><s:text name="criterion.template" /></option></s:if>
+ <s:else> <option value="TEMPLATE" ><s:text name="criterion.template" /></option></s:else>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td colspan=5 align=left>
+ <s:if test="visibility == 'PRIVATE'">
+ <input type=radio name="visibility" value="PRIVATE" checked onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="PUBLIC" onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" onClick="changeFilter()"><s:text name="field.either"/>
+ </s:if>
+ <s:elseif test="visibility == 'PUBLIC'">
+ <input type=radio name="visibility" value="PRIVATE" onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="PUBLIC" checked onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" onClick="changeFilter()"><s:text name="field.either"/>
+ </s:elseif>
+ <s:elseif test="visibility == 'onlypublic'">
+ <input type=radio name="visibility" value="PRIVATE" disabled onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="onlypublic" checked onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" disabled onClick="changeFilter()"><s:text name="field.either"/>
+ </s:elseif>
+ <s:else>
+ <input type=radio name="visibility" value="PRIVATE" onClick="changeFilter()"><s:text name="field.private"/>
+ <input type=radio name="visibility" value="PUBLIC" onClick="changeFilter()"><s:text name="field.public"/>
+ <input type=radio name="visibility" value="all" checked onClick="changeFilter()"><s:text name="field.either"/>
+ </s:else>
+ </td>
+ </tr>
+ <tr>
+ <td colspan=2><s:text name="criterion.author"/> </td>
+ <td colspan=3 align=center>
+ <select name="author" style="width: <s:text name="size.search.select"/>" onChange="changeFilter()">
+ <option value="0"><s:text name="criterion.anybody" /></option>
<s:iterator value="candidates">
<s:if test="%{index == #him}">
<option value="<s:property value="index"/>" selected><s:property value="toString()"/></option>
</s:else>
</s:iterator>
</select>
- </div>
- <div id="article-item">
-<% if (anonymous) {
-%> <input type=radio name="owner" value="mine" disabled><font color="#A1A192"><s:text name="criterion.study.mine"/></font>
-<% } else {
-%> <s:if test="owner == 'mine'">
- <input type=radio name="owner" value="mine" checked onClick="unsetReference()"><s:text name="criterion.study.mine"/>
- </s:if><s:else>
- <input type=radio name="owner" value="mine" onClick="unsetReference()"><s:text name="criterion.study.mine"/>
- </s:else>
-<% } %> </div>
- <div id="article-item">
- <s:if test="owner == 'ref'">
- <input type=radio name="owner" value="ref" checked onClick="setReference()"><s:text name="criterion.study.ref"/>
- </s:if><s:else>
- <input type=radio name="owner" value="ref" onClick="setReference()"><s:text name="criterion.study.ref"/>
- </s:else>
- <div id=refid>
- <input type=text name="reference" value="<s:property value="%{reference}"/>" size="18" onKeydown="changeFilter()"/>
- </div>
- </div>
+ </td>
+ </tr>
+ <tr>
+ <s:set var="tipdate">
+ <s:text name="help.search.date">
+ <s:param><s:text name="%{#format}"/></s:param>
+ <s:param><s:text name="%{#today}"/></s:param>
+ </s:text>
+ </s:set>
+ <td><s:text name="field.credate"/> </td>
+ <td><s:text name="field.after"/> </td>
+ <td><input type=text name=after size=7 onKeydown="changeFilter()" title="<s:property value="%{#tipdate}"/>" /> </td>
+ <td><s:text name="field.before"/> </td>
+ <td><input type=text name=before size=7 onKeydown="changeFilter()" title="<s:property value="%{#tipdate}"/>" /></td>
+ </tr><tr>
+ <td><s:text name="field.lasdate"/> </td>
+ <td><s:text name="field.after"/> </td>
+ <td><input type=text name=after size=7 onKeydown="changeFilter()" title="<s:property value="%{#tipdate}"/>" /> </td>
+ <td><s:text name="field.before"/> </td>
+ <td><input type=text name="before" size=7 onKeydown="changeFilter()" title="<s:property value="%{#tipdate}"/>" /></td>
+ </tr>
+ </table>
+ <table cellpadding=0 cellspacing=0 border=0 class=text>
+ <tr>
+ <td><s:text name="field.contain"/>: </td>
+ <td><input type=text name=words style="width: <s:text name="size.search.input"/>" value="<s:property value="%{words}"/>" onKeydown="changeFilter()" title="<s:text name="help.search.title"/>" /></td>
+ </tr><tr>
+ <td><s:text name="field.reference"/>: </td>
+ <td><input type=text name="reference" style="width: <s:text name="size.search.input"/>" value="<s:property value="%{reference}"/>" onKeydown="changeFilter()" title="<s:text name="help.search.refid"/>" /></td>
+ </tr>
+ </table>
</td>
- <td rowspan=2>
- <div id=contlist>
-
+ <td width=60%>
<table cellpadding=0 cellspacing=0 border=0 class=text>
<s:iterator value="simulationContexts">
<tr>
</s:iterator>
</select>
</s:if>
- </div>
- </td>
- </tr>
- <tr>
- <td>
- <div id=wordin>
- <br/><s:text name="field.contain"/> : <input type=text name=words value="<s:property value="%{words}"/>" onKeydown="changeFilter()" />
- </div>
</td>
</tr>
+ </table>
+
+ <table width=100% cellpadding=0 cellspacing=0 border=0 class=text>
<tr>
- <td></td>
- <td align=left>
- <input type="submit" name="refresh" value="<s:text name="button.result"/>" disabled/>
- </td>
+ <td width=40%></td>
+ <td width=60% align=left><input type="submit" name="refresh" value="<s:text name="button.result"/>" disabled/></td>
</tr>
</table>
title.login = Saisissez vos coordonnées
+title.criteria = Critères de recherche
title.newstudy = Entrez les caractéristiques de votre étude
title.newscenario = Ajout d''un scénario
title.private = Dans mon espace de travail
field.product = Produit étudié
field.among = Parmi
field.context = Contexte
+field.matchall = Tous les critères
+field.matchany = Au moins un
+field.private = Me concernant
+field.public = Publiques
+field.either = N''importe
+field.credate = Créé
+field.lasdate = Modifié
+field.after = après
+field.before = avant
field.contain = Dont le titre contient
+field.reference = Dont la reference est
field.contextype = Type de contexte
field.documentype = Type du document
field.upload = Fichier à télécharger
field.context.value = Valeur
-criterion.study.all = Toutes les études
-criterion.study.mine = Mes études
-criterion.study.his = Les études de
-criterion.study.ref = L''étude référencée...
-criterion.knowledge.all = Toutes les
-criterion.knowledge.mine = Toutes mes connaissances
-criterion.knowledge.his = Les acquis de
-criterion.knowledge.ref = La connaissance référencée...
-criterion.inprogress = En cours
-criterion.indraft = A valider
-criterion.incheck = A approuver
-criterion.approved = Terminées
-criterion.archived = Archivées
-criterion.template = Modèles
+criterion.study = Les études
+criterion.knowledge = Toutes les
+criterion.author = Dont l''auteur est
+criterion.inwork = en cours
+criterion.indraft = Ã valider
+criterion.incheck = Ã approuver
+criterion.approved = approuvées
+criterion.template = de référence
+criterion.any = quel que soit leur état
+criterion.anybody = indifférent
-size.study.state = 158px
-size.study.author = 179px
-size.knowledge.state = 201px
-size.knowledge.author = 180px
+size.search.select = 192px
+size.search.input = 160px
button.newstudy = Créer l''étude
tooltip.refresh = Actualiser
tooltip.close = Fermer
tooltip.cancel = Abandonner
+
tooltip.shared = Document partagé entre plusieurs scénarios
tooltip.versioned = Document modifié dans cette version de l''étude
help.contextcode = Le code interne est un nom utilisable depuis l''interface de programmation pour référencer les contextes de simulation indépendamment de leur nom affiché à l''écran dans la langue en cours.
+help.search.date = Saisissez une date dans le format {0}.\nExemple: {1}
+help.search.title = Saisissez tous les termes qui doivent correspondre, si besoin avec des caractères de remplacement simples (symbole \?) ou multiples (symbole \*).
+help.search.refid = Saisissez votre reference, si besoin avec des caractères de remplacement simples (symbole \?) ou multiples (symbole \*).
message.welcome = Bienvenue dans votre outil de gestion des études de simulation.
title.login = Enter your login identification
+title.criteria = Search criteria
title.newstudy = Define your study
title.newscenario = Add a scenario
title.private = From my Workspace
field.scenariotitle = Title of the scenario
field.documentitle = Title of the document
field.product = Studied product
-field.among = Amongst
+field.among = Among
field.context = Context
+field.matchall = Match all of
+field.matchany = Match any of
+field.private = I''m involved in
+field.public = Public
+field.either = Either
+field.credate = Created
+field.lasdate = Modified
+field.after = after
+field.before = before
field.contain = Whose title contains
+field.reference = Whose reference is
field.contextype = Context type
field.documentype = Document type
field.upload = File to be uploaded
field.context.value = Value
-criterion.study.all = All studies
-criterion.study.mine = My studies
-criterion.study.his = The studies of
-criterion.study.ref = The study referenced...
-criterion.knowledge.all = All the
-criterion.knowledge.mine = All my knowledges
-criterion.knowledge.his = Knowledges of
-criterion.knowledge.ref = The knowledge referenced...
-criterion.inprogress = on going
-criterion.indraft = currently being reviewed
-criterion.incheck = currently being approved
-criterion.approved = completed
-criterion.archived = archived
-criterion.template = making a Template
+criterion.study = All studies
+criterion.knowledge = All the
+criterion.author = Authored by
+criterion.inwork = in-progress
+criterion.indraft = to be validated
+criterion.incheck = to be approved
+criterion.approved = approved
+criterion.template = approved as reference
+criterion.any = whatever their status
+criterion.anybody = anybody
-size.study.state = 202px
-size.study.author = 182px
-size.knowledge.state = 226px
-size.knowledge.author = 179px
+size.search.select = 197px
+size.search.input = 150px
button.newstudy = Create the study
tooltip.shared = Document shared by several scenarios
tooltip.versioned = Document modified in this version of the study
+
help.contextcode = The internal code is a name used from the Application Programming Interface for referencing the simulation contexts apart from any locale (English, French, Russian or whatever).
+help.search.date = Enter a date in the format {0}.\nExample: {1}
+help.search.title = Enter all terms the title must match, possibly with single (\? symbol) and multiple (\* symbol) character wildcard searches.
+help.search.refid = Enter your reference, possibly with single (\? symbol) and multiple (\* symbol) character wildcard searches.
message.welcome = Welcome to your Simulation Study Management Tool.
import org.apache.log4j.Logger;
import org.splat.kernel.User;
-import org.splat.kernel.XDOM;
+import org.splat.manox.XDOM;
import org.splat.som.Document;
import org.splat.som.DocumentRights;
import org.splat.som.DocumentType;
import org.splat.wapp.PopupMenu;
import org.splat.wapp.PopupItem;
import org.splat.wapp.SimpleMenu;
-import org.splat.wapp.TabBar;
import org.splat.wapp.ToolBar;
// Default customizable mandatory settings
Map<String, Object> fprop = new HashMap<String, Object>();
- TabBar sbar = new TabBar();
- sbar.addItem("private", "search-study?area=private");
- sbar.addItem("public", "search-study?area=public");
- sbar.addItem("reference", "search-study?area=reference");
- sbar.selects("private");
- fprop.put("area", sbar);
- fprop.put("state", "inPROGRESS");
+ fprop.put("visibility", "PRIVATE");
+ fprop.put("matchamong", "all");
+ fprop.put("matcontext", "all");
+ fprop.put("state", "END");
fprop.put("author", "0");
- fprop.put("owner", "all");
fprop.put("reference", "");
fprop.put("title", "");
fprop.put("context", new Vector<SimulationContext>());
Map<String, Object> gprop = new HashMap<String, Object>();
- sbar = new TabBar();
- sbar.addItem("private", "search-knowledge?area=private");
- sbar.addItem("public", "search-knowledge?area=public");
- sbar.addItem("reference", "search-knowledge?area=reference");
- sbar.selects("public");
- gprop.put("area", sbar);
- gprop.put("author", "0");
- gprop.put("owner", "all");
+ gprop.put("visibility", "PUBLIC");
+ gprop.put("matchamong", "all");
+ gprop.put("matcontext", "all");
gprop.put("type", "2"); //TODO: Get the index from the type name
+ gprop.put("author", "0");
gprop.put("reference", "");
gprop.put("title", "");
gprop.put("context", new Vector<SimulationContext>());
import org.splat.kernel.User;
import org.splat.som.ApplicationRights;
import org.splat.som.Database;
-import org.splat.wapp.TabBar;
import java.io.IOException;
import javax.security.auth.login.FailedLoginException;
if (logged.canContributeToStudy() || logged.canValidate()) {
//TODO: Set the search filter according to user preferences
Map<String,Object> session = getSession();
- Map<String,Object> kfilter = (Map<String, Object>)session.get("knowledge.filter");
+// Map<String,Object> kfilter = (Map<String, Object>)session.get("knowledge.filter");
Map<String,Object> sfilter = (Map<String, Object>)session.get("study.filter");
- TabBar kbar = (TabBar)kfilter.get("area");
- TabBar sbar = (TabBar)sfilter.get("area");
- kbar.enables("private");
- sbar.enables("private");
- sbar.selects("private");
- if (logged.canCreateStudy()) sfilter.put("owner", "mine"); // Supposed being initialized to "all"
+ sfilter.put("state", "ANY");
+ sfilter.put("visibility", "PRIVATE");
+ if (logged.canCreateStudy()) sfilter.put("author", String.valueOf(user.getIndex()));
}
this.connect(context, user); // Updates the session context
return backmenu;
// -------------------------
try {
Map<String,Object> session = getSession();
- Map<String,Object> kfilter = (Map<String, Object>)session.get("knowledge.filter");
+// Map<String,Object> kfilter = (Map<String, Object>)session.get("knowledge.filter");
Map<String,Object> sfilter = (Map<String, Object>)session.get("study.filter");
LoginContext context = (LoginContext)session.get("login.context");
context.logout();
//TODO: ProjectSettings.deleteDownloadDirectory(user);
- sfilter.put("owner", "all");
- ((TabBar)sfilter.get("area")).disables("private");
- ((TabBar)kfilter.get("area")).disables("private");
+ sfilter.put("state", "ANY");
+ sfilter.put("author", "0");
this.disconnect(); // Updates the session context
return backmenu;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.splat.kernel.InvalidPropertyException;
+import org.splat.kernel.Name;
import org.splat.kernel.User;
import org.splat.kernel.UserDirectory;
import org.splat.som.ApplicationRights;
protected String ctype = null; // Context type index, when selected
protected String cvalue = null; // Context value index, when selected
protected String cindex = ""; // Context index, when removed
- protected String newarea = null; // Selected repository area
protected String author = null;
- protected List<User> manager = null;
+ protected List<Name> manager = null;
protected SimulationContextType newtype; // Context type to be valued
protected List<SimulationContext> newvalue; // Context value to be selected
protected List<SimulationContextType> critext; // Addable context types
// --------------------------
return author;
}
- public List<User> getCandidates () {
+ public List<Name> getCandidates () {
// ----------------------------------
return manager;
}
// Setters
// ==============================================================================================================================
- public void setArea (String name) {
-// ---------------------------------
- this.newarea = name;
- }
public void setAuthor (String index) {
// ------------------------------------
this.author = index;
protected void setCandidates () {
// -------------------------------
- manager = new Vector<User>();
+ manager = new Vector<Name>();
List<User> users = UserDirectory.selectAllUsers();
User me = getConnectedUser(); // May be null
for (Iterator<User> i=users.iterator(); i.hasNext(); ) {
- User next = i.next();
- if ( next.equals(me) ) continue;
- ApplicationRights he = new ApplicationRights(next);
- if (he.canCreateStudy()) manager.add(next);
+ User next = i.next();
+ ApplicationRights he = new ApplicationRights(next);
+ if (he.canCreateStudy()) {
+ if (next.equals(me)) manager.add(0, new ValidationFacade.ByManager(me));
+ else manager.add(next);
+ }
}
}
import org.splat.som.SimulationContext;
import org.splat.som.SimulationContextType;
import org.splat.som.Visibility;
-import org.splat.wapp.Item;
-import org.splat.wapp.TabBar;
public class SearchKnowledgeAction extends SearchBaseAction {
- private TabBar area = null; // Active repository area
- private String among = null; // "all", "inCHECK" or "ref"
- private String typid = null; // Knowledge type index when among all
- private String refid = null; // Knowledge reference when among ref
- private String words = null; // Full text search words
+ private String visibility = null; // "Private", "Public", "All"
+ private String typid = null; // Knowledge type index when among all
+ private String matchamong = null; // "all" or "any"
+ private String matcontext = null; // "all" or "any"
+ private String refid = null; // Knowledge reference when among ref
+ private String words = null; // Full text search words
private List<KnowledgeElementType> types; // Available knowledge types filter (initialized below)
private static final long serialVersionUID = -3104321907432838476L;
Transaction transax = connex.beginTransaction();
try {
loadFilter();
- if (newarea != null) { // New selected repository area
- area.selects(newarea);
- }
doSearch();
// Final initialization of the form
User user = getConnectedUser();
KnowledgeElement.Properties sprop = new KnowledgeElement.Properties();
- KnowledgeElement.Properties other = null;
-
-// Set of the selected repository area
- String selectab = area.getSelection().toUpperCase();
- Visibility reparea = Visibility.valueOf(selectab);
- sprop.setVisibility(reparea);
-
-// Search from a given reference
- if (among.equals("ref")) {
- if (refid.length() == 0) {
- getSession().remove("search.result"); // The current result is obsolete
- return "wait";
- }
- sprop.setReference(refid);
- if (reparea == Visibility.PRIVATE) { // Restriction to studies in which the connected user is involved
- other = sprop.copy().setActor(user);
- sprop.setAuthor(user);
- }
- } else {
-// Search from other available criteria
+
+// Search matching all criteria
+ sprop.setType( KnowledgeElement.selectType(Integer.valueOf(typid)) );
if (words.length() > 0) sprop.setTitle(words);
+ if (refid.length() > 0) sprop.setReference(refid);
if (context.size() > 0) sprop.setSimulationContexts(context);
- if ( among.equals("mine") ) sprop.setAuthor(user);
- else if ( among.equals("his") ) {
- User him = UserDirectory.selectUser(Integer.valueOf(author));
+ int index = Integer.valueOf(author);
+ if (index > 0) {
+ User him = UserDirectory.selectUser(index);
sprop.setAuthor(him);
- if (reparea == Visibility.PRIVATE) sprop.setActor(user);
- } else {//among.equals("all")
- KnowledgeElementType type = KnowledgeElement.selectType(Integer.valueOf(typid));
- sprop.setType(type);
- if (reparea == Visibility.PRIVATE) { // Restriction to studies in which the connected user is involved
- other = sprop.copy().setActor(user);
- sprop.setAuthor(user);
- }
}
- }
- if (other == null) result = Database.selectKnowledgeElementsWhere(sprop);
- else result = Database.selectKnowledgeElementsWhere(sprop, other);
+// Set of the visibility
+ if (visibility.equals("all")) {
+ KnowledgeElement.Properties other = sprop.copy();
+
+ other.setVisibility(Visibility.PUBLIC);
+ sprop.setVisibility(Visibility.PRIVATE);
+ sprop.setActor(user);
+ result = Database.selectKnowledgeElementsWhere(sprop, other);
+ }
+ else {
+ Visibility reparea = null;
+ if (visibility.equals("onlypublic")) reparea = Visibility.PUBLIC;
+ else reparea = Visibility.valueOf(visibility);
+ sprop.setVisibility(reparea);
+ if (reparea == Visibility.PRIVATE) sprop.setActor(user);
+
+ result = Database.selectKnowledgeElementsWhere(sprop);
+ }
session.put("search.result", result); // For redisplaying the page without re-executing the search
return "refresh";
}
// Getters
// ==============================================================================================================================
+ public String getContextMatch () {
+// --------------------------------
+ return matcontext;
+ }
+ public String getCriteriaMatch () {
+// ---------------------------------
+ return matchamong;
+ }
public List<KnowledgeElementType> getKnowledgeTypes () {
// ------------------------------------------------------
return types;
}
- public String getOwner () {
-// -------------------------
- return among;
- }
public String getReference () {
// -----------------------------
return refid;
// ------------------------
return typid;
}
- public List<Item> getTabs () {
-// ----------------------------
- return area.asList();
+ public String getVisibility () {
+// ------------------------------
+ return visibility;
}
public String getWords () {
// -------------------------
// Setters
// ==============================================================================================================================
- public void setOwner (String value) {
-// -----------------------------------
- this.among = value;
+ public void setContextMatch (String value) {
+// ------------------------------------------
+ this.matcontext = value;
+ }
+ public void setCriteriaMatch (String value) {
+// -------------------------------------------
+ this.matchamong = value;
}
public void setReference (String value) {
// ---------------------------------------
// ----------------------------------
this.typid = value;
}
+ public void setVisibility (String value) {
+// ----------------------------------------
+ this.visibility = value;
+ }
public void setWords (String value) {
// -----------------------------------
this.words = value;
User user = getConnectedUser();
Map<String,Object> filter = (Map<String, Object>)session.get("knowledge.filter"); // A default filter is supposed being set at start
- area = (TabBar)filter.get("area");
- among = (String)filter.get("owner");
- author = (String)filter.get("author");
- typid = (String)filter.get("type");
- refid = (String)filter.get("reference");
- words = (String)filter.get("title");
- context = (List<SimulationContext>)filter.get("context");
+ visibility = (String)filter.get("visibility");
+ matchamong = (String)filter.get("matchamong");
+ matcontext = (String)filter.get("matcontext");
+ typid = (String)filter.get("type");
+ author = (String)filter.get("author");
+ refid = (String)filter.get("reference");
+ words = (String)filter.get("title");
+ context = (List<SimulationContext>)filter.get("context");
if (user == null) {
- area.disables("private");
- if (area.getSelection().equals("private")) area.selects("public");
+ visibility = "onlypublic";
}
}
Map<String,Object> session = getSession();
Map<String,Object> filter = (Map<String, Object>)session.get("knowledge.filter"); // A default filter is supposed being set at start
- area = (TabBar)filter.get("area"); // The area being not an input, it is null when submitting the form
- if (among.equals("ref")) {
- filter.put("owner", "ref");
- filter.put("reference", this.refid);
- } else {
- filter.put("owner", this.among);
- filter.put("author", this.author);
- filter.put("type", this.typid);
- filter.put("reference", "");
- filter.put("title", this.words);
-
- context = (List<SimulationContext>)filter.get("context"); // Only criteria not part of the form
- }
+ filter.put("visibility", this.visibility);
+ filter.put("matchamong", this.matchamong);
+ filter.put("matcontext", this.matcontext);
+ filter.put("type", this.typid);
+ filter.put("author", this.author);
+ filter.put("reference", "");
+ filter.put("title", this.words);
+
+ context = (List<SimulationContext>)filter.get("context"); // Only criteria not part of the form
+
// Initialization required by all do functions
types = KnowledgeElement.selectTypesWhere(ProgressState.APPROVED);
}
import org.splat.som.SimulationContextType;
import org.splat.som.Study;
import org.splat.som.Visibility;
-import org.splat.wapp.Item;
-import org.splat.wapp.TabBar;
public class SearchStudyAction extends SearchBaseAction {
- private TabBar area = null; // Active repository area
- private String state = null; // "inPROGRESS", "inCHECK" or "END"
- private String among = null; // "all", "mine" or "ref"
- private String refid = null; // Study reference when among ref
- private String words = null; // Full text search words
+ private String visibility = null; // "Private", "Public", "All"
+ private String state = null; // "In-Work", "In-Draft", "In-Check"...
+ private String matchamong = null; // "all" or "any"
+ private String matcontext = null; // "all" or "any"
+ private String refid = null; // Study reference
+ private String words = null; // Full text search words
private static final long serialVersionUID = -1910481357051393077L;
// Action methods
// ==============================================================================================================================
- public String doInitialize () {
+ public String doInitialize () {
// -----------------------------
Session connex = Database.getSession();
Transaction transax = connex.beginTransaction();
try {
loadFilter();
- if (newarea != null) { // New selected repository area
- area.selects(newarea);
- }
doSearch();
// Final initialization of the form
}
}
- protected String doSearch () throws InvalidPropertyException {
+ protected String doSearch () throws InvalidPropertyException {
// ----------------------------
Map<String, Object> session = getSession();
User user = getConnectedUser();
Study.Properties sprop = new Study.Properties();
- Study.Properties other = null;
-
-// Set of the selected repository area
- String selectab = area.getSelection().toUpperCase();
- Visibility reparea = Visibility.valueOf(selectab);
- sprop.setVisibility(reparea);
-
-// Search from a given reference
- if (among.equals("ref")) {
- if (refid.length() == 0) {
- getSession().remove("search.result"); // The current result is obsolete
- return "wait";
- }
- sprop.setReference(refid);
- if (reparea == Visibility.PRIVATE) { // Restriction to studies in which the connected user is involved
- other = sprop.copy().setActor(user);
- sprop.setManager(user);
+
+// Search matching all criteria
+ if (!this.state.equals("ANY")) sprop.setState( ProgressState.valueOf(this.state) );
+ if (words.length() > 0) sprop.setTitle(words);
+ if (refid.length() > 0) sprop.setReference(refid);
+ if (context.size() > 0) sprop.setSimulationContexts(context);
+ int index = Integer.valueOf(author);
+ if (index > 0) {
+ User him = UserDirectory.selectUser(index);
+ sprop.setManager(him);
}
- } else {
-// Search from other available criteria
- if (this.state != null) {
- ProgressState state = ProgressState.APPROVED; // Trick for the Public and Reference areas to not share the APPROVED state
- if (!this.state.equals("ARCHIVED")) state = ProgressState.valueOf(this.state);
- sprop.setState(state);
+// Set of the visibility
+ if (visibility.equals("all")) {
+ Study.Properties other = sprop.copy();
+
+ other.setVisibility(Visibility.PUBLIC);
+ sprop.setVisibility(Visibility.PRIVATE);
+ sprop.setActor(user);
+
+ result = Database.selectStudiesWhere(sprop, other);
}
- if (words.length() > 0) sprop.setTitle(words);
- if (context.size() > 0) sprop.setSimulationContexts(context);
- if (among.equals("mine")) sprop.setManager(user);
- else if (among.equals("his")) {
- User him = UserDirectory.selectUser(Integer.valueOf(author));
- sprop.setManager(him);
+ else {
+ Visibility reparea = null;
+ if (visibility.equals("onlypublic")) reparea = Visibility.PUBLIC;
+ else reparea = Visibility.valueOf(visibility);
+ sprop.setVisibility(reparea);
if (reparea == Visibility.PRIVATE) sprop.setActor(user);
- } else //among.equals("all")
- if (reparea == Visibility.PRIVATE) {
- other = sprop.copy().setActor(user);
- sprop.setManager(user);
- }
- }
- if (other == null) result = Database.selectStudiesWhere(sprop);
- else result = Database.selectStudiesWhere(sprop, other);
+ result = Database.selectStudiesWhere(sprop);
+ }
session.put("search.result", result); // For redisplaying the page without re-executing the search
return "refresh";
}
// Getters
// ==============================================================================================================================
- public String getArea () {
-// ------------------------
- return area.getSelection();
+ public String getContextMatch () {
+// --------------------------------
+ return matcontext;
}
- public String getOwner () {
-// -------------------------
- return among;
+ public String getCriteriaMatch () {
+// ---------------------------------
+ return matchamong;
}
public String getReference () {
// -----------------------------
// -------------------------
return state;
}
- public List<Item> getTabs () {
-// ----------------------------
- return area.asList();
+ public String getVisibility () {
+// ------------------------------
+ return visibility;
}
public String getWords () {
// -------------------------
// Setters
// ==============================================================================================================================
- public void setOwner (String value) {
-// -----------------------------------
- this.among = value;
+ public void setContextMatch (String value) {
+// ------------------------------------------
+ this.matcontext = value;
+ }
+ public void setCriteriaMatch (String value) {
+// -------------------------------------------
+ this.matchamong = value;
}
public void setReference (String value) {
// ---------------------------------------
// -----------------------------------
this.state = value;
}
+ public void setVisibility (String value) {
+// ----------------------------------------
+ this.visibility = value;
+ }
public void setWords (String value) {
// -----------------------------------
this.words = value;
User user = getConnectedUser();
Map<String,Object> filter = (Map<String, Object>)session.get("study.filter"); // A default filter is supposed being set at start
- area = (TabBar)filter.get("area");
- state = (String)filter.get("state");
- among = (String)filter.get("owner");
- author = (String)filter.get("author");
- refid = (String)filter.get("reference");
- words = (String)filter.get("title");
- context = (List<SimulationContext>)filter.get("context");
+ visibility = (String)filter.get("visibility");
+ matchamong = (String)filter.get("matchamong");
+ matcontext = (String)filter.get("matcontext");
+ state = (String)filter.get("state");
+ author = (String)filter.get("author");
+ refid = (String)filter.get("reference");
+ words = (String)filter.get("title");
+ context = (List<SimulationContext>)filter.get("context");
if (user == null) {
- area.disables("private");
- if (area.getSelection().equals("private")) area.selects("public");
- if (among.equals("mine")) among = "all";
+ visibility = "onlypublic";
}
}
Map<String, Object> session = getSession();
Map<String, Object> filter = (Map<String, Object>)session.get("study.filter"); // A default filter is supposed being set at start
- area = (TabBar)filter.get("area"); // The area being not an input, it is null when submitting the form
- if (among.equals("ref")) {
- filter.put("owner", "ref");
- filter.put("reference", this.refid);
- } else {
- filter.put("state", this.state);
- filter.put("owner", this.among);
- filter.put("author", this.author);
- filter.put("reference", "");
- filter.put("title", this.words);
-
- context = (List<SimulationContext>)filter.get("context"); // Only criteria not part of the form
- }
+ filter.put("visibility", this.visibility);
+ filter.put("matchamong", this.matchamong);
+ filter.put("matcontext", this.matcontext);
+ filter.put("state", this.state);
+ filter.put("author", this.author);
+ filter.put("reference", this.refid);
+ filter.put("title", this.words);
+
+ context = (List<SimulationContext>)filter.get("context"); // Only criteria not part of the form
+
}
}
\ No newline at end of file
schema.version = D-0.3
wapp.version = D-0.5
-wapp.root = D:/users/rkv/SIMAN/Workspace/Siman/WebContent/
+wapp.root = D:/users/rkv/SIMAN/SIMAN_SRC/Workspace/Siman/WebContent/
wapp.login = conf/login.conf
wapp.configuration = conf/som.xml
wapp.customization = conf/my.xml
schema.version = D-0.3
wapp.version = D-0.5
-wapp.root = D:/users/rkv/SIMAN/Workspace/Siman/WebContent/
+wapp.root = D:/users/rkv/SIMAN/SIMAN_SRC/Workspace/Siman/WebContent/
wapp.login = conf/login.conf
wapp.configuration = conf/som.xml
wapp.customization = conf/my.xml