import java.io.File;
import java.io.FileNotFoundException;
-import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
-import java.util.Vector;
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.splat.kernel.InvalidPropertyException;
import org.splat.dal.bo.kernel.Relation;
import org.splat.dal.bo.kernel.User;
-import org.splat.manox.Reader;
-import org.splat.manox.Toolbox;
-import org.splat.dal.dao.som.Database;
import org.splat.dal.bo.som.Document;
import org.splat.dal.bo.som.ProgressState;
-import org.splat.service.PublicationService;
-import org.splat.service.StepService;
-import org.splat.service.technical.ProjectSettingsService;
-import org.splat.service.technical.RepositoryService;
import org.splat.dal.bo.som.Publication;
-import org.splat.som.Revision;
-import org.splat.som.Step;
import org.splat.dal.bo.som.UsedByRelation;
import org.splat.dal.bo.som.UsesRelation;
+import org.splat.dal.bo.som.ValidationCycle;
+import org.splat.dal.bo.som.ValidationStep;
+import org.splat.kernel.InvalidPropertyException;
+import org.splat.manox.Reader;
+import org.splat.manox.Toolbox;
+import org.splat.som.Revision;
+import org.splat.som.Step;
+import org.splat.wapp.Constants;
-public class VersionDocumentAction extends UploadBaseNextAction {
+/**
+ * Action for creating a new version of a document.
+ */
+public class VersionDocumentAction extends BaseUploadDocumentAction {
- private String index = null; // Versioned document index
- private List<Publication> usedby = null;
- private String docusedby = null;
- private String summary = null; // Summary of changes in the new version
- private String docver = ""; // Version number extracted from the imported file, if exist
- private String date = ""; // Date extracted from the imported file, if exist
- private ProjectSettingsService _projectSettingsService;
- private PublicationService _publicationService;
- private StepService _stepService;
/**
- * Injected repository service.
+ * Serial version ID.
*/
- private RepositoryService _repositoryService;
+ private static final long serialVersionUID = -5702264003232132168L;
+
/**
- * Value of the menu property.
- * It can be: none, create, open, study, knowledge, sysadmin, help.
+ * Versioned document index.
*/
- private String _menuProperty;
-
+ private String _index = null;
/**
- * Value of the title bar property.
- * It can be: study, knowledge.
+ * List of publications which use the selected document.
*/
- private String _titleProperty;
-
+ private transient List<Publication> _usedby = null;
/**
- * Property that indicates whether the current open study is editable or not.
- * On the screen it looks like pen on the status icon, pop-up menu also can be called.
- * It is necessary for correct building the title bar.
+ * List of selected impacted documents ids.
*/
- private String _editDisabledProperty = "false";
-
+ private transient long[] _docusedby = null;
/**
- * Serial version ID.
+ * Summary of changes in the new version.
*/
- private static final long serialVersionUID = -5702264003232132168L;
-
- // ==============================================================================================================================
- // Action methods
- // ==============================================================================================================================
+ private String _description = null;
+ /**
+ * Applicable document states.
+ */
+ private transient final List<ProgressState> _documentStates = new ArrayList<ProgressState>();
+ /**
+ * Initialize the action form.
+ *
+ * @return SUCCESS if succeeded, ERROR if uploaded file is XML and we can't extract properties from it
+ */
public String doInitialize() {
- // -----------------------------
-
- setMenuProperty("study");
- setTitleProperty("study");
- setEditDisabledProperty("true");
- initializationScreenContext(_menuProperty, _titleProperty, _editDisabledProperty);
-
- Session connex = Database.getCurSession();
- Transaction transax = connex.beginTransaction();
- User user = getConnectedUser();
- File updir = getRepositoryService().getDownloadDirectory(user);
- File upfile = new File(updir.getPath() + "/" + filename);
-
- mystudy = getOpenStudy();
+ File upfile = commonInitialize(Constants.TRUE);
- Publication tag = mystudy.getSelectedStep().getDocument(
- Integer.valueOf(index));
+ _mystudy = getOpenStudy();
+ _mystudy.updateCurrentStep();
+ _defuses = new ArrayList<Document>();
+
+ Publication tag = _mystudy.getSelectedStep().getDocument(
+ Integer.valueOf(_index));
Document doc = tag.value();
- deftype = doc.getType();
- docname = doc.getTitle();
- defuses = new Vector<Document>();
- usedby = new Vector<Publication>();
+ _deftype = doc.getType();
+ _docname = doc.getTitle();
+ _usedby = new ArrayList<Publication>();
+
+ String res = SUCCESS;
+ if (extractProperties(upfile, doc)) {
+ if (_deftype != null) {
+ setupDefaultUses(_deftype);
+ }
+ // Add additional documents used by the current version
+ for (Relation usesRel : doc.getRelations(UsesRelation.class)) {
+ Document used = (Document) usesRel.getTo();
+ Document lastVersion = getPublicationService().getLastVersion(used, tag.getOwner());
+ if (lastVersion != null && !_defuses.contains(lastVersion)) {
+ _defuses.add(lastVersion);
+ }
+ }
+ // Avoid recursive using of the document
+ if (_defuses.contains(doc)) {
+ _defuses.remove(doc);
+ }
+
+ // Avoid using of documents dependent on the current version of the document being versioned
+ // (This case is possible only if both documents belong to the step of the same Project Element)
+ for(Iterator<Document> document = _defuses.iterator(); document.hasNext(); ) {
+ Publication pub = tag.getOwner().getPublication(document.next());
+ if(pub != null && pub.getRelations(UsesRelation.class).contains(tag)) {
+ document.remove();
+ }
+ }
+
+ // Setup dependencies
+ _usedby.addAll(tag.getRelations(UsedByRelation.class));
+
+ // Initialize applicable states list
+ if (tag.value().getProgressState() == ProgressState.EXTERN) {
+ _documentStates.add(ProgressState.EXTERN);
+ } else {
+ _documentStates.add(ProgressState.inWORK);
+ if (_deftype != null) {
+ // Check if the validation cycle of the document type can has a review state
+ ValidationCycle cycle = getStudyService()
+ .getValidationCycleOf(_mystudy.getMystudy(),
+ _deftype);
+ if ((cycle != null) && cycle.enables(ValidationStep.REVIEW)) {
+ _documentStates.add(ProgressState.inDRAFT);
+ }
+ }
+ }
+ } else {
+ if (!(Constants.NONE.equals(getToolProperty()))) {
+ initializationFullScreenContext(Constants.STUDY_MENU,
+ Constants.STUDY_MENU, Constants.TRUE, Constants.NONE,
+ Constants.STUDY_MENU);
+ }
+ res = ERROR;
+ }
+ return res;
+ }
+ /**
+ * Try to extract properties from the uploaded file if it is XML.
+ *
+ * @param upfile
+ * the file to parse
+ * @param doc
+ * the document to version
+ * @return true if succeeded or if the file is not XML, otherwise return false
+ */
+ private boolean extractProperties(final File upfile, final Document doc) {
+ boolean res = true;
Reader tool = Toolbox.getReader(upfile);
if (tool != null) {
String fileref = tool.extractProperty("reference");
String filever = tool.extractProperty("version");
- if (fileref != null && !doc.getReference().equals(fileref)) {
- setErrorCode("reference.mismatch");
- return ERROR;
- }
- if (filever != null)
- try {
- Revision.Format get = new Revision.Format(
- getProjectSettings().getRevisionPattern());
- Revision newver = get.parse(filever);
- Revision oldver = new Revision(doc.getVersion());
- if (!newver.isGraterThan(oldver))
- throw new InvalidPropertyException("version");
- if (newver.isMinor())
- state = ProgressState.inWORK;
- else
- state = ProgressState.inDRAFT;
- docver = newver.toString();
- } catch (Exception e) {
- setErrorCode("version.mismatch");
- return ERROR;
+ if (fileref == null || doc.getReference().equals(fileref)) {
+ if (filever != null) {
+ try {
+ Revision.Format get = new Revision.Format(
+ getProjectSettings().getRevisionPattern());
+ Revision newver = get.parse(filever);
+ Revision oldver = new Revision(doc.getVersion());
+ if (!newver.isGraterThan(oldver)) {
+ throw new InvalidPropertyException("version");
+ }
+ if (newver.isMinor()) {
+ _state = ProgressState.inWORK;
+ } else {
+ _state = ProgressState.inDRAFT;
+ }
+ setVersion(newver.toString());
+ } catch (Exception e) {
+ setErrorCode("message.error.version.mismatch");
+ res = false;
+ }
}
- summary = tool.extractProperty("history");
- date = tool.extractProperty("date");
- if (date != null) {
- ResourceBundle locale = ResourceBundle.getBundle("som",
- ApplicationSettings.getCurrentLocale());
- SimpleDateFormat check = new SimpleDateFormat(
- locale.getString("date.format"));
- try {
- check.parse(date);
- } catch (ParseException e) {
- setErrorCode("format.date");
- return ERROR;
+ if (res) {
+ _description = tool.extractProperty("history");
+ res = extractDate(tool);
}
- } else
- date = "";
- }
- setupDefaultUses(deftype);
- // Add additional documents used by the current version
- List<Relation> uses = doc.getRelations(UsesRelation.class);
- for (Iterator<Relation> i = uses.iterator(); i.hasNext();) {
- Document used = (Document) i.next().getTo();
- if (!defuses.contains(used))
- defuses.add(used);
- }
- // Setup dependencies
- List<Publication> relist = tag.getRelations(UsedByRelation.class);
- for (Iterator<Publication> i = relist.iterator(); i.hasNext();) {
- usedby.add(i.next());
+ } else {
+ setErrorCode("message.error.reference.mismatch");
+ res = false;
+ }
}
- transax.commit();
- return SUCCESS;
+ return res;
}
+ /**
+ * Create a new version of the selected document.
+ *
+ * @return SUCCESS - if succeeded, "cancel" - if canceled, ERROR - if failed
+ */
public String doVersion() {
- // -------------------------
- setMenuProperty("study");
- setTitleProperty("study");
- setEditDisabledProperty("true");
- initializationScreenContext(_menuProperty, _titleProperty, _editDisabledProperty);
-
- if (action == ToDo.cancel)
- return "cancel";
+ String res = ERROR;
+ initializationScreenContext(Constants.STUDY_MENU, Constants.STUDY_MENU,
+ Constants.TRUE);
- Session connex = Database.getCurSession();
- Transaction transax = connex.beginTransaction();
- try {
- // Getting user inputs
- mystudy = getOpenStudy();
- User user = getConnectedUser();
- Step step = mystudy.getSelectedStep();
- File updir = getRepositoryService().getDownloadDirectory(user);
- File upfile = new File(updir.getPath() + "/" + filename);
+ if (_action == ToDo.cancel) {
+ res = "cancel";
+ } else {
- // Versioning of the document
- Document.Properties dprop = new Document.Properties();
- Publication current = step.getDocument(Integer.valueOf(index));
- Publication next;
-
- if (docver.length() == 0) { // Importation of a foreign document
- next = getStepService().versionDocument(step, current, dprop.setAuthor(user)
- .setDescription(summary));
- updir = next.getSourceFile().asFile();
- if (logger.isInfoEnabled())
- logger.info("Moving \"" + upfile.getName() + "\" to \""
- + updir.getPath() + "\".");
- upfile.renameTo(updir);
- try {
- getPublicationService().saveAs(next, state); // May throw FileNotFound if rename was not done
- } catch (FileNotFoundException saverror) {
- Thread.sleep(1000);
- logger.info("Waiting for the file.");
- upfile.renameTo(updir);
- getPublicationService().saveAs(next, state); // Forget it if throw again FileNotFound
- }
- } else {
- if (date.length() > 0) {
+ try {
+ // Getting user inputs
+ _mystudy = getOpenStudy();
+ User user = getConnectedUser();
+ Step step = _mystudy.getSelectedStep();
+ Date aDate = null;
+ if (getDocumentDate().length() > 0) {
ResourceBundle locale = ResourceBundle.getBundle("som",
- ApplicationSettings.getCurrentLocale());
- SimpleDateFormat get = new SimpleDateFormat(
- locale.getString("date.format"));
- dprop.setDate(get.parse(date));
+ getApplicationSettings().getCurrentLocale());
+ SimpleDateFormat get = new SimpleDateFormat(locale
+ .getString("date.format"), getApplicationSettings()
+ .getCurrentLocale());
+ aDate = get.parse(getDocumentDate());
}
- next = getStepService().versionDocument(step, current, dprop.setAuthor(user)
- .setDescription(summary));
- updir = next.getSourceFile().asFile();
- if (logger.isInfoEnabled())
- logger.info("Moving \"" + upfile.getName() + "\" to \""
- + updir.getPath() + "\".");
- upfile.renameTo(updir);
- try {
- getPublicationService().saveAs(next, new Revision(docver));
- } catch (FileNotFoundException saverror) {
- Thread.sleep(1000);
- logger.info("Waiting for the file.");
- upfile.renameTo(updir);
- getPublicationService().saveAs(next, state);
- }
- }
- // TODO: Remove current document details from the contents of open study
- // Creation of uses relations
- if (docuses != null) {
- String[] list = docuses.split(",");
- for (int i = 0; i < list.length; i++) {
- Integer index = Integer.valueOf(list[i].trim());
- Publication used = getPublication(index);
- next.addDependency(used);
+ String[] listDocuses = null;
+ if (_docuses != null) {
+ listDocuses = _docuses.split(",");
}
+ getPublicationService().versionDocument(step, user, _fileName,
+ Integer.valueOf(_index), getVersion(), _description,
+ _state, aDate, listDocuses, _docusedby);
+
+ // Update of the open study
+ refreshStudy();
+
+ res = SUCCESS;
+ } catch (FileNotFoundException error) {
+ LOG.error("Reason:", error);
+ setErrorCode("message.error.import.file");
+ } catch (Exception error) {
+ LOG.error("Reason:", error);
+ setErrorCode("message.error.internal");
}
- // Outdating impacted document
- HashSet<Integer> compatible = new HashSet<Integer>();
- if (docusedby != null) {
- String[] list = docusedby.split(",");
- for (int i = 0; i < list.length; i++)
- compatible.add(Integer.valueOf(list[i].trim()));
- }
- List<Publication> relist = current
- .getRelations(UsedByRelation.class);
- for (Iterator<Publication> i = relist.iterator(); i.hasNext();) {
- Publication using = i.next();
- if (!compatible.contains(using.getIndex()))
- getPublicationService().outdate(using);
- }
- // Update of the open study
- mystudy.setSelection(mystudy.getSelection()); // Rebuilds the presentation
- // TODO: Look is an optimization is possible (for example by updating the presentation of versioned document)
-
- transax.commit();
- return SUCCESS;
- } catch (FileNotFoundException error) {
- logger.error("Reason:", error);
- setErrorCode("import.file");
- } catch (Exception error) {
- logger.error("Reason:", error);
- setErrorCode("internal");
- }
- if (transax != null && transax.isActive()) {
- // Second try-catch as the rollback could fail as well
- try {
- transax.rollback();
- } catch (HibernateException backerror) {
- logger.debug("Error rolling back transaction", backerror);
+ if (!SUCCESS.equals(res)) {
+ initializationFullScreenContext(Constants.STUDY_MENU,
+ Constants.STUDY_MENU, Constants.TRUE, Constants.NONE,
+ Constants.STUDY_MENU);
}
}
- return ERROR;
+ return res;
}
// ==============================================================================================================================
// Getters and setters
// ==============================================================================================================================
- public String getDate() {
- // ------------------------
- return date;
- }
-
public List<Publication> getDependencies() {
- // -------------------------------------------
- return usedby;
+ return _usedby;
}
public String getDescription() {
- // -------------------------------
- return summary;
+ return _description;
}
public String getIndex() {
- // -------------------------
- return index;
- }
-
- public String getVersion() {
- // ---------------------------
- return docver;
- }
-
- public void setDate(String date) {
- // ---------------------------------
- this.date = date;
- }
-
- public void setDefaultDescription(String summary) {
- // --------------------------------------------------
- if (this.summary == null)
- this.summary = summary;
+ return _index;
}
- public void setDescription(String summary) {
- // -------------------------------------------
- this.summary = summary;
- }
-
- public void setIndex(String index) {
- // -----------------------------------
- this.index = index;
+ public void setDefaultDescription(final String summary) {
+ if (this._description == null) {
+ this._description = summary;
+ }
}
- public void setUsedBy(String list) {
- // -----------------------------------
- this.docusedby = list;
+ public void setDescription(final String summary) {
+ this._description = summary;
}
- public void setVersion(String value) {
- // -------------------------------------
- this.docver = value;
+ public void setIndex(final String index) {
+ this._index = index;
}
- /**
- * Get project settings.
- *
- * @return Project settings service
- */
- private ProjectSettingsService getProjectSettings() {
- return _projectSettingsService;
+ public void setUsedBy(final long[] list) {
+ this._docusedby = list;
}
/**
- * Set project settings service.
+ * Get the documentStates.
*
- * @param projectSettingsService
- * project settings service
- */
- public void setProjectSettings(ProjectSettingsService projectSettingsService) {
- _projectSettingsService = projectSettingsService;
- }
-
- /**
- * Get the publicationService.
- *
- * @return the publicationService
- */
- public PublicationService getPublicationService() {
- return _publicationService;
- }
-
- /**
- * Set the publicationService.
- *
- * @param publicationService
- * the publicationService to set
- */
- public void setPublicationService(PublicationService publicationService) {
- _publicationService = publicationService;
- }
-
- /**
- * Get the stepService.
- * @return the stepService
- */
- public StepService getStepService() {
- return _stepService;
- }
-
- /**
- * Set the stepService.
- * @param stepService the stepService to set
- */
- public void setStepService(StepService stepService) {
- _stepService = stepService;
- }
-
- /**
- * Get the repositoryService.
- * @return the repositoryService
- */
- public RepositoryService getRepositoryService() {
- return _repositoryService;
- }
-
- /**
- * Set the repositoryService.
- * @param repositoryService the repositoryService to set
- */
- public void setRepositoryService(RepositoryService repositoryService) {
- _repositoryService = repositoryService;
- }
-
- /**
- * Get the menuProperty.
- * @return the menuProperty
- */
- public String getMenuProperty() {
- return _menuProperty;
- }
-
- /**
- * Set the menuProperty.
- * @param menuProperty the menuProperty to set
- */
- public void setMenuProperty(String menuProperty) {
- this._menuProperty = menuProperty;
- }
-
- /**
- * Get the _titleProperty.
- * @return the _titleProperty
- */
- public String getTitleProperty() {
- return _titleProperty;
- }
-
- /**
- * Set the _titleProperty.
- * @param _titleProperty the titleProperty to set
- */
- public void setTitleProperty(String titleProperty) {
- _titleProperty = titleProperty;
- }
-
- /**
- * Get the _editDisabledProperty.
- * @return the _editDisabledProperty
- */
- public String getEditDisabledProperty() {
- return _editDisabledProperty;
- }
-
- /**
- * Set the _editDisabledProperty.
- * @param _editDisabledProperty the _editDisabledProperty to set
+ * @return the documentStates
*/
- public void setEditDisabledProperty(String _editDisabledProperty) {
- this._editDisabledProperty = _editDisabledProperty;
+ public List<ProgressState> getDocumentStates() {
+ return _documentStates;
}
}
\ No newline at end of file