Search the FirstSpirit Knowledge Base
Hallo zusammen,
ich würde gerne Objekte mit Hilfe eines Workflow und eines Scripts freigeben. Das geht ja mit der Server-Freigabe "AccessUtil.release()".
Wie prüfe ich den davor ob eine Seite valide ist? Wir haben viele Regeln, die auf ON_RELEASE basieren.
Problem ist, sobald eine Seite nicht valide ist, wirft das Script mir ein Fehler zurück und die Seite bleibt im Arbeitsablauf stecken.
Danke für eure Antworten.
Hallo,
da ich es gerade sowieso selbst benutzt hatte hier ein Minimalbeispiel:
final MultiFormValidationReport validationReport = context.requireSpecialist(ValidationAgent.TYPE).validate(idProvider, ValidationAgent.ValidationScope.RELEASE);
result= validationReport.isValid(); //true if everything is OK
Der idProvider ist dann z.B. die Seite.
Achtung: Enthaltene Absätze werden hier nicht mitgeprüft, hierfür müssten entsprechend separate Aufrufe benutzt werden.
Alternative:
Ein Release per AccessUtil im "Testmodus" versuchen und sich dann die problematischen Elemente bzgl. ReleaseProgress.ProblemType.VALIDATION_FAILED geben lassen. Das wäre aber etwas mehr Code.
Hier muss man außerdem aufpassen, auf was genau geprüft werden soll - man könnte z.B. auf die Idee kommen, generell bei einem "Misserfolg" des allgemeinen Release-Tests abzubrechen. Gerade wenn mehrere Elemente im Spiel sind, passt das aber nicht unbedingt.
Beispiel: Testet man die (gemeinsame!) Freigabemöglichkeit einer Seitenreferenz und einer noch nie freigegebenen Inhaltsseite (ohne Validierungsprobleme!), auf die diese Seitenreferenz verweist, kommt es - im Testmodus - natürlich zu einem anderen Fehler weil beim Freigabetest der Seitenreferenz die Inhaltsseite eben noch nicht freigegeben ist.
Viele Grüße
Michael
Das ist über die Klasse ValidationAgent möglich.
Danke für Ihre schnelle Antwort.
Können Sie mir ein kurzes Beispiel geben?
Hallo,
da ich es gerade sowieso selbst benutzt hatte hier ein Minimalbeispiel:
final MultiFormValidationReport validationReport = context.requireSpecialist(ValidationAgent.TYPE).validate(idProvider, ValidationAgent.ValidationScope.RELEASE);
result= validationReport.isValid(); //true if everything is OK
Der idProvider ist dann z.B. die Seite.
Achtung: Enthaltene Absätze werden hier nicht mitgeprüft, hierfür müssten entsprechend separate Aufrufe benutzt werden.
Alternative:
Ein Release per AccessUtil im "Testmodus" versuchen und sich dann die problematischen Elemente bzgl. ReleaseProgress.ProblemType.VALIDATION_FAILED geben lassen. Das wäre aber etwas mehr Code.
Hier muss man außerdem aufpassen, auf was genau geprüft werden soll - man könnte z.B. auf die Idee kommen, generell bei einem "Misserfolg" des allgemeinen Release-Tests abzubrechen. Gerade wenn mehrere Elemente im Spiel sind, passt das aber nicht unbedingt.
Beispiel: Testet man die (gemeinsame!) Freigabemöglichkeit einer Seitenreferenz und einer noch nie freigegebenen Inhaltsseite (ohne Validierungsprobleme!), auf die diese Seitenreferenz verweist, kommt es - im Testmodus - natürlich zu einem anderen Fehler weil beim Freigabetest der Seitenreferenz die Inhaltsseite eben noch nicht freigegeben ist.
Viele Grüße
Michael
Hallo Michael,
Danke für deine Antwort. Dein Alternativweg klingt spannend.
Wie rufe ich dann die Methode ReleaseProgress auf?
Hallo Timo,
hier mal ein Stückchen Code wie es (in etwa) funktionieren sollte (nicht ausführlich getestet, nur als Einstiegspunkt!).
Achtung: Das funktioniert nicht auf Datasets, die lassen sich nicht per AccessUtil freigeben - d.h. dafür müsstest Du wieder den ValidationAgent benutzen. Die continues kommen daher dass ich im Ursprungscode eine Liste von IDProvidern in einer Schleife abfrage - also ggf. durch eine andere Logik ersetzen 😉
Ggf. kannst Du hier schon (mit "alles OK") abbrechen wenn das serverActionHandle.getResult(); ein Boolean.TRUE zurück liefert.
Store store=...
IDProvider idProvider=...
Boolean result=true;
String elementInfo=store.getName()+"/"+idProvider.getElementType()+"/"+(idProvider.hasUid()?("UID:"+idProvider.getUid()):("ID:"+idProvider.getId()));
final ServerActionHandle<? extends ReleaseProgress, Boolean> serverActionHandle = AccessUtil.release(idProvider, true);
try {
serverActionHandle.getResult();
} catch (Exception e) {
Logging.logError("Release Check threw exception", e, getClass());
return false;
}
final ReleaseProgress releaseResult = serverActionHandle.getProgress(true);
final EnumMap<ReleaseProgress.ProblemType, Set<Long>> problematicElements = releaseResult.getProblematicElements();
String passedMessage="PASSED: "+elementInfo;
if (problematicElements.isEmpty()) {
Logging.logDebug(passedMessage,getClass());
continue;
}
final Set<Long> problematicIds = problematicElements.get(ReleaseProgress.ProblemType.VALIDATION_FAILED);
if(problematicIds==null){
Logging.logDebug(passedMessage,getClass());
continue;
}
if (problematicIds.contains(idProvider.getId())) {
result=false;
}
...
return result;
Viele Grüße
Michael
Hallo Timo,
benötigst Du noch weitere Hilfe oder haben Dir die Antworten von Christoph und Michael bereits geholfen?
In diesem Fall wäre es super, wenn Du die "richtige Antwort" entsprechend markierst, damit auch andere
Community-Teilnehmer diese auf den ersten Blick finden. Solltest Du zwischenzeitlich eine eigene Lösung
gefunden haben, wäre es nett, wenn Du diese hier bereitstellst.
Viele Grüße
Marian Zaplatynski
Hallo Michael,
wir arbeiten an einem Script und ich bin über ein Problem gestolpert. Bei meiner Fehlersuche habe ich diesen Beitrag gefunden, weil du hier etwas erfolgreich benutzt, was mir der Parser bisher verweigert.
Ich möchte an die EnumMap, die mir
releaseResult.getProblematicElements()
liefert. Mittlerweile scheint sich zu deinem Beispiel hier die Signatur der Methode etwas geändert zu haben. Mein aktueller API-Stand hat hier
EnumMap<ReleaseProblem, Set<BasicInfo>>
als Rückgabeparameter. Wenn ich aber eine passende Variable definiere, meckert mir der Parser das Komma an:
EnumMap<ReleaseProblem, Set<BasicInfo>> problematicElements = releaseResult.getProblematicElements();
Ich bekomme hier beim Speichern die Meldung:
Fehlerhafte Syntax
bsh.ParseException: Parse error at line 47, column 47. Encountered: ,.
Wenn ich mein Script in eine IDE werfe, wird kein Fehler angezeigt.
Hast du (oder wer anderes) eine Idee, was hier schief geht?
Ich lege unten noch das ganze Script zum Testen ab.
Cheers
Connz
//!Beanshell
import de.espirit.firstspirit.access.store.BasicInfo;
import de.espirit.firstspirit.access.store.ReleaseProblem;
import de.espirit.firstspirit.access.store.Store;
import de.espirit.firstspirit.access.store.globalstore.GCAPage;
import de.espirit.firstspirit.access.store.globalstore.GlobalStoreRoot;
import de.espirit.firstspirit.agency.OperationAgent;
import de.espirit.firstspirit.agency.SpecialistsBroker;
import de.espirit.firstspirit.agency.StoreAgent;
import de.espirit.firstspirit.store.operations.ReleaseOperation;
import de.espirit.firstspirit.ui.operations.RequestOperation;
import de.espirit.firstspirit.webedit.server.ClientScriptOperation;
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
String FOOTER_UID = "gc_footer";
SpecialistsBroker specialistsBroker = context;
GlobalStoreRoot globalStoreRoot = (GlobalStoreRoot) specialistsBroker.requireSpecialist(StoreAgent.TYPE).getStore(Store.Type.GLOBALSTORE);
OperationAgent operationAgent = specialistsBroker.requireSpecialist(OperationAgent.TYPE);
ReleaseOperation releaseOperation = operationAgent.getOperation(ReleaseOperation.TYPE);
ClientScriptOperation clientScriptOperation = operationAgent.getOperation(ClientScriptOperation.TYPE);
// Release Footer
GCAPage gcaPage = globalStoreRoot.getGcaByName(FOOTER_UID);
if(gcaPage != null && releaseOperation != null) {
ReleaseOperation.ReleaseResult releaseResult = releaseOperation.perform(gcaPage);
// Inform User of Result
RequestOperation dialog = operationAgent.getOperation(RequestOperation.TYPE);
String dialogTitle = "";
String dialogPerformMessage = "";
dialog.setTitle("Footer Release Status");
if(dialog != null) {
if(releaseResult.isSuccessful()){
dialogTitle = "The Release of the Footer was Successful";
dialogPerformMessage = "Released elements: " + releaseResult.getReleasedElements();
} else {
dialog.setKind(RequestOperation.Kind.WARN);
dialogTitle = "The Release of the Footer was Unsuccessful";
EnumMap<ReleaseProblem, Set<BasicInfo>> problematicElements = releaseResult.getProblematicElements();
dialogPerformMessage = "Encountered problems: " + problematicElements;
}
dialog.setTitle(dialogTitle);
dialog.addOk();
dialog.perform(dialogPerformMessage);
}
clientScriptOperation.perform("WE_API.Preview.reload();", true);
}
Hi Connz,
der Beanshell-Parser hat ein paar Einschränkungen bzgl. Generics. Was unter anderem nicht geht (nach meinem letzten Stand aus dem Kopf - habs länger nicht im Detail getestet):
Das bezieht sich aber nur auf die Deklaration. Da man in Beanshell aber nicht so exakt typisieren muss (und eigentlich sogar komplett auf Deklarationen verzichten kann - wobei ich da kein Fan von bin…), wäre hier eine Lösung einfach nur
EnumMap problematicElements = …
zu benutzen.
Viele Grüße
Michael
Hey @mbergmann,
es wäre super, wenn das irgendwo dokumentiert wäre! Man denkt bei sowas ja als erstes immer daran, dass man selber irgendwo einen ollen Tippfehler o.ä. hat und sucht dann vergeblich.
Ich bin auch kein Freund davon die Typisierung wegzulassen, daher hier auch meine Frage. Aber mit der Version funktioniert es und damit hatte ich auch weiter getestet bis...
Der nächste Punkt, den der Parser auch nicht mag, sind Lambda-Ausdrücke. Hier
problematicElements.entrySet().stream().filter(releaseProblemSetEntry -> !releaseProblemSetEntry.getValue().isEmpty())
mag der Parser wieder das ">" nicht.
Das ist echt schade, weil man das zwar auch alles mit einer Schleife etc. hinbekommt, aber so ist es IMHO schöner und viel verständlicher, was hier passiert.
Gibt es da Bestrebungen den Parser zu aktualisieren? Wie ist der beste Weg das voran zu bringen?
Cheers
Connz