{
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");
+ if (value == null) throw new MissedPropertyException("value");
}
}
// Database fetch constructor
*/
DocToCompareDTO getDocToCompareDTO(long publicationId)
throws InvalidParameterException;
+
+ /**
+ * Check if this publication is outdated and other publications used by it are up-to-date.
+ *
+ * @param aPublication
+ * the publication
+ * @return true if succeeded
+ */
+ boolean canBeActualized(Publication aPublication);
}
import org.splat.dal.bo.som.ProgressState;
import org.splat.dal.bo.som.ProjectElement;
import org.splat.dal.bo.som.Publication;
+import org.splat.dal.bo.som.Scenario;
import org.splat.dal.bo.som.SimulationContext;
import org.splat.dal.bo.som.SimulationContextType;
import org.splat.dal.bo.som.Study;
*/
@Transactional(readOnly=true)
public Document getLastVersion(final Document doc, final ProjectElement owner) {
- Document theLastVersion = _documentService.selectDocument(doc.getIndex()); //get document attached to hibernate session
+ Document document = _documentService.selectDocument(doc.getIndex()); //get document attached to hibernate session
ProjectElement trueOwner = _projectElementDAO.merge(owner);
- if(trueOwner.getPublication(theLastVersion) == null) { //start recursive search
+ Document theLastVersion = null;
+ if(trueOwner.getPublication(document) != null) {
+ theLastVersion = document;
+ } else { //start recursive search
List<VersionsRelation> relations = _versionsRelationDAO
.getFilteredList(Restrictions.eq("refer", theLastVersion));
//there may be several next versions if document is shared between scenarios,
}
}
}
- if(theLastVersion != null && trueOwner.getPublication(theLastVersion) == null) {
- theLastVersion = null;
+ if(theLastVersion == null && owner instanceof Scenario) {
+ theLastVersion = getLastVersion(doc, ((Scenario)owner).getOwnerStudy());
}
return theLastVersion;
}
- /**
- * Check if this publication is outdated and other publications used by it are up-to-date.
- *
- * @param aPublication
- * the publication
- * @return true if succeeded
+ /**
+ * {@inheritDoc}
+ * @see org.splat.service.PublicationService#canBeActualized(org.splat.dal.bo.som.Publication)
*/
@Transactional(readOnly=true)
- private boolean canBeActualized(final Publication aPublication) {
+ public boolean canBeActualized(final Publication aPublication) {
boolean res = aPublication.isOutdated();
for(Publication used : aPublication.getRelations(UsesRelation.class)) {
if(used.isOutdated()) {
*/
@Transactional
public boolean actualize(final Publication aPublication) {
- boolean res = aPublication.isOutdated() && canBeActualized(aPublication);
+ Publication mergedPublication = getPublicationDAO().merge(aPublication);
+ boolean res = aPublication.isOutdated();
if (res) {
//Replace dependencies to old versions of documents with dependencies to the latest versions.
- for(Relation rel : aPublication.value().getRelations(UsesRelation.class)) {
+ for(Relation rel : mergedPublication.value().getRelations(UsesRelation.class)) {
Document used = (Document)rel.getTo();
- if(aPublication.getOwnerStudy().getPublication(used) == null) {
- aPublication.value().removeRelation(UsesRelation.class, used);
+ if(mergedPublication.getOwnerStudy().getPublication(used) == null) {
+ mergedPublication.value().removeRelation(UsesRelation.class, used);
//There is always a last version
- Document theLastVersion = getLastVersion(used, aPublication.getOwner());
- aPublication.addDependency(theLastVersion);
+ Document theLastVersion = getLastVersion(used, mergedPublication.getOwner());
+ mergedPublication.addDependency(theLastVersion);
}
}
- aPublication.setIsnew('Y');
- getPublicationDAO().update(aPublication);
-
- //recursively actualize all documents that don't use any more outdated documents.
- for(Publication using : aPublication.getRelations(UsedByRelation.class)) {
- actualize(using);
- }
+ mergedPublication.setIsnew('Y');
+ getPublicationDAO().update(mergedPublication);
+
+// //recursively actualize all documents that don't use any more outdated documents.
+// for(Publication using : aPublication.getRelations(UsedByRelation.class)) {
+// actualize(using); //by the way, the recursive call won't be transactional as it is not called via spring proxy
+// }
}
return res;
}
* the userService to set
*/
void setUserService(UserService userService);
+
+ /**
+ * Get the publicationService.
+ *
+ * @return the publicationService
+ */
+ PublicationService getPublicationService();
+ /**
+ * Set the publicationService.
+ *
+ * @param publicationService
+ * the publicationService to set
+ */
+ void setPublicationService(PublicationService publicationService);
}
* Injected user service.
*/
private UserService _userService;
+ /**
+ * Injected publication service.
+ */
+ private PublicationService _publicationService;
/**
* Get the studyService.
public void setUserService(final UserService userService) {
_userService = userService;
}
+
+ /**
+ * Get the publicationService.
+ * @return the publicationService
+ */
+ public PublicationService getPublicationService() {
+ return _publicationService;
+ }
+
+ /**
+ * Set the publicationService.
+ * @param publicationService the publicationService to set
+ */
+ public void setPublicationService(final PublicationService publicationService) {
+ _publicationService = publicationService;
+ }
}
* @see org.splat.service.StepService#addSimulationContext(org.splat.som.Step, org.splat.dal.bo.som.SimulationContext.Properties)
*/
@Override
+ @Transactional
public SimulationContext addSimulationContext(final Step aStep,
final SimulationContext.Properties dprop)
throws MissedPropertyException, InvalidPropertyException,
* @see Publication#accept()
*/
public boolean canAccept() {
- return _isauthor && _operand.isOutdated();
+ return _isauthor && ServiceLocatorImpl.getInstance()
+ .getPublicationService().canBeActualized(_operand);
}
/**
public boolean canApprove() {
User approver = _cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
boolean res = (_user.equals(approver))
- && (_operand.getProgressState() == ProgressState.inCHECK);
+ && (_operand.getProgressState() == ProgressState.inCHECK)
+ && !_operand.isOutdated();
if (res) {
List<Relation> use = _operand.value().getRelations(
UsesRelation.class);
User manager = _operand.getOwnerStudy().getAuthor();
User publisher = _cycle.getActor(ValidationStep.PROMOTION); // Null if the default users are involved
+ if(_operand.isOutdated()) {
+ return false;
+ }
if (_operand.getProgressState() != ProgressState.inWORK) {
if (_operand.getProgressState() == ProgressState.inDRAFT) {
return canReview();
public boolean canReview() {
User reviewer = _cycle.getActor(ValidationStep.REVIEW); // May be null if not reviewable
- if (!_user.equals(reviewer)) {
+ if (!_user.equals(reviewer) || _operand.isOutdated()) {
return false;
}
if (_operand.getProgressState() != ProgressState.inDRAFT) {
*/
public boolean canApprove() {
User approver = _cycle.getActor(ValidationStep.APPROVAL); // May be null if not approvable
- return (_user.equals(approver))
+ return (_user.equals(approver) || _isauthor)
&& getStudyService().canBeApproved(_operand);
}
return res;
}
+
+ /**
+ * Checks if the user has right to rename a scenario of the study.
+ *
+ * @return true if user in an author, contributor or a validation cycle member of the study.
+ */
+ public boolean canRenameScenario() {
+ return _isauthor || getStudyService().hasActor(_operand, _user);
+ }
// ==============================================================================================================================
// Getter
factory-method="getInstance">
<property name="studyService" ref="studyService" />
<property name="userService" ref="userService" />
+ <property name="publicationService" ref="publicationService" />
</bean>
<bean id="userService" class="org.splat.service.UserServiceImpl">
<img src="<s:url value="/skin/%{stateIcon}"/>" width=14 height=14 border="none" title=""/>
</s:else>
</td>
- <td><img src="<s:url value="/skin/%{fileIcon}"/>" border="none" title=""/></td>
+ <td>
+ <s:a href="%{URL}" target="_blank" cssClass="link">
+ <img src="<s:url value="/skin/%{fileIcon}"/>" border="none" title=""/> </s:a>
+ </td>
<td>
<s:if test="%{curAction == 'renameDocument'}">
<s:if test="%{#selectedDocIndex == #docindex}">
</s:else>
</td>
<td><img src="<s:url value="/skin/%{stateIcon}"/>" width=14 height=14 border="none" title=""/></td>
- <td><img src="<s:url value="/skin/%{fileIcon}"/>" border="none" title=""/></td>
+ <td>
+ <s:a href="%{URL}" target="_blank" cssClass="link">
+ <img src="<s:url value="/skin/%{fileIcon}"/>" border="none" title=""/> </s:a>
+ </td>
<td>
<s:a href="%{URL}" target="_blank" cssClass="link"><s:property value="title"/></s:a>
</td>
</s:if>
<!-- Scenario ckecked-in (editable)
- --> <s:else>
+ --> <s:elseif test="%{openStudy.StudyRights.canRenameScenario()}">
<s:form name="property" action="valid-rename" method="post" validate="true" cssClass="text">
<tr>
<td><s:text name="field.scenariotitle"/>: <span class="error">*</span></td>
</td>
</tr>
</s:form>
- </s:else>
+ </s:elseif><s:else>
+ <table>
+ <tr height="28">
+ <td valign="middle"><s:text name="field.scenariotitle"/>: </td>
+ <td>
+ <s:text name="%{selectedScenarioTitle}"/>
+ </td>
+ </tr>
+ </table>
+ </s:else>
</div>
</div>
* Demote icon file name.
*/
private static final String IMG_DEMOTE = "image.demote.png";
+ /**
+ * Accept icon file name.
+ */
+ private static final String IMG_ACCEPT = "image.accept.png";
/**
* Attach menu item name.
* Rename menu item name.
*/
private static final String MNU_RENAME = "rename";
+ /**
+ * Set up-to-date menu item name.
+ */
+ private static final String MNU_ACTUALIZE = "accept";
/**
* Attach menu item name.
* Remove as reference menu item label key.
*/
private static final String MNU_NAME_REMOVE_AS_REFERENCE = "menu.removeasreference";
+ /**
+ * Set up-to-date menu item label key.
+ */
+ private static final String MNU_NAME_ACTUALIZE = "menu.actualize";
// /**
// * Not yet implemented action name.
// */
* Promote the study action name.
*/
private static final String ACT_PROMOTE_STUDY = "edit-study?action=promote";
+ /**
+ * Set up-to-date action name.
+ */
+ private static final String ACT_ACTUALIZE = "setDocument?action=accept";
/**
* Siman application server name.
*/
private EditableDocumentPopup() {
super();
- /*
- * addItem("accept", new PopupItem("menu.accept").icon( "image.accept.png").action("setDocument?action=accept")
- * .confirmation("message.accept.document"));
- */
+ addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
+ .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
+ .confirmation("message.actualize.document"));
addItem(MNU_PROMOTE, new PopupItem(MNU_NAME_PROMOTE).icon(
IMG_PROMOTE).action("setDocument?action=promote")
.confirmation("message.promote.document"));
*/
private ReviewableDocumentPopup() {
super();
+ addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
+ .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
+ .confirmation("message.actualize.document"));
addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
IMG_DEMOTE).action("setDocument?action=demote")
.confirmation("message.demote.document"));
*/
private NotResultDocumentPopup() {
super();
+ addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
+ .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
+ .confirmation("message.actualize.document"));
addItem(MNU_DEMOTE, new PopupItem(MNU_NAME_DEMOTE).icon(
IMG_DEMOTE).action("setDocument?action=demote")
.confirmation("message.demote.document"));
*/
private ApprovableDocumentPopup() {
super();
+ addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
+ .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
+ .confirmation("message.actualize.document"));
+
/*addItem("undo", new PopupItem(MNU_NAME_DEMOTE).icon(
"image.invalidate.png").action(
"setDocument?action=invalidate").confirmation(
*/
private ApprovedPopup() {
super();
+ addItem(MNU_ACTUALIZE, new PopupItem(MNU_NAME_ACTUALIZE)
+ .icon(IMG_ACCEPT).action(ACT_ACTUALIZE)
+ .confirmation("message.actualize.document"));
addItem(MNU_ATTACH, new PopupItem(MNU_NAME_ATTACH).icon(IMG_ATTACH)
.action(ACT_ATTACH));
addSeparator();
_display = State.deepopen;
} else { // Opening the document
if (_uses == null) {
- List<Relation> used = _me.value().getRelations(UsesRelation.class);
-
- _uses = new ArrayList<DocumentFacade>();
- for(Relation relation : used) {
- Document doc = (Document)relation.getTo();
- Publication pub = _me.getOwner().getPublication(
- _publicationService.getLastVersion(doc, _me.getOwner()));
- DocumentFacade facade = _owner._docpres.get(pub.getIndex());
- if (facade == null && pub != null) {
- facade = new DocumentFacade(_owner, pub,
+ List<Relation> relist = _me.value().getRelations(UsesRelation.class);
+
+ _uses = new ArrayList<DocumentFacade>(relist.size());
+ for (Relation relation : relist) {
+ Document used = ((UsesRelation)relation).getTo();
+
+ DocumentFacade facade = null;
+
+ Publication publication = _me.getOwner().getPublication(used);
+ if(publication == null) {
+ publication = _me.getOwnerStudy().getPublication(used);
+ }
+ if(publication != null) {
+ facade = _owner._docpres.get(publication.getIndex());
+ }
+
+ if (facade == null) {
+ facade = new DocumentFacade(_owner, used,
getProjectSettings(), getPublicationService(),
getApplicationSettings());
- _owner._docpres.put(pub.getIndex(), facade);
}
_uses.add(facade);
}
setAction(null);
} else if (todo == Execute.accept) {
getPublicationService().actualize(doc);
- _openStudy.update(doc);
+ doOpen(); //so pop-up menus of documents depending on this one will be updated
} else if (todo == Execute.promote) {
getPublicationService().promote(doc,
Calendar.getInstance().getTime());
package org.splat.simer;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import org.splat.dal.bo.som.ProjectElement;
if (_newtype.length() == 0 || _value.length() == 0) {
res = INPUT;
+ setAction("newContext");
} else {
Step step = _openStudy.getSelectedStep();
protected void update(final Publication doc) {
DocumentFacade facade = _docpres.get(doc.getIndex());
if (facade != null) {
- facade.refresh();
+ _contents.remove(facade);
+ facade = new DocumentFacade(this, doc,
+ getProjectSettings(), getPublicationService(),
+ getApplicationSettings());
+ _docpres.put(doc.getIndex(), facade);
+ _contents.add(facade);
}
}
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
// Add additional documents used by the current version
for (Relation usesRel : doc.getRelations(UsesRelation.class)) {
Document used = (Document) usesRel.getTo();
- if (!_defuses.contains(getPublicationService().getLastVersion(used, tag.getOwner()))) {
- _defuses.add(used);
+ 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));