Search the FirstSpirit Knowledge Base
Hallo,
ich versuche zur Zeit ein Script zu schreiben, mit dessen Hilfe sich eine Absatz-Referenz "überschreiben" lässt. Das Ziel ist, dass nach Rechtsklick > Script ausführen > Absatz überschreiben die vorhandene Referenz mit einer Kopie des Quell-Absatzes ersetzt wird.
Es funktioniert leider nur, bis man mehr als einen Absatz überschreiben will, denn da erscheinen vorher gelöschte Absatz-Referenzen auf einmal wieder.
Also, das funktioniert: Script anstoßen, Bearbeitungsmodus verlassen, wieder starten, nochmal Script anstoßen (wiederhole mal x, kein Problem).
Funktioniert NICHT: Script anstoßen, Bearbeitungsmodus nicht verlassen, Script nochmal anstoßen -> gelöschte Absätze wieder da.
Ich habe schon herumexperimientiert mit setLock(), refresh() (was auch immer das genau macht), ohne Bearbeitungsmodus Script anstoßen, … immer dasselbe Ergebnis. Irgend ein wichtiger Teil scheint mir da im Script zu fehlen.
Dies ist der entsprechende Teil aus meinem Script:
targetPage.setLock(true);
targetSectionIndex = targetBody.getChildIndex(targetSection);
sourceSection = targetSection.getReference();
newSection = AccessUtil.copyStoreElement(sourceSection, targetBody);
AccessUtil.cloneStoreElement(context.getProject(), targetSection); // deprecated, ich weiß… werde es ersetzen, sobald es funktioniert 😉
targetBody.moveChild(newSection, targetSectionIndex);
targetBody.removeChild(targetSection);
Kann mir jemand weiterhelfen? Vielen Dank!
Hallo Herr Cordes,
bitte mal die Hinweise unter Locking-Hints umsetzen. Eventuell ist das schon die Lösung des Problems.
Viele Grüße
Christoph Feddersen
Ich habe das Script entsprechend angepasst, aber leider ändert das am Verhalten nichts.
Wobei ich bei targetPage.release(true) immer folgenden Fehler bekomme:
de.espirit.firstspirit.access.script.ExecutionException: Method Invocation targetPage.release at line 45 (<- kann ich leider gerade gar nichts mit anfagen).
Stattdessen verwende ich targetPage.setLock(false, true)) – müsste doch auch gehen?
Es muss einen Unterschied geben, ob ich "manuell" aus dem Bearbeitungsmodus gehe, nachdem ich das Script ausgeführt habe oder via Script setLock(false) aufrufe.
Hinweis: das AccessUtil.cloneStoreElement(
… aus dem Snippet oben ist in Wirklichkeit auskommentiert, ich benutze nur das AccessUtil.copyStoreElement().
Bitte mal das komplette Skript und den kompletten Stacktrace der Fehlermeldung posten. Die verwendete FirstSpirit-Version wäre ebenfalls interessant.
FirstSpirit Client 4.2.446.45868
Version Server: 4.2.446.45868
Java Version: 1.6.0_31 32bit Apple Inc.
Betriebssystem: Mac OS X 10.7.3 i386
Das komplette Script:
//!Beanshell
import de.espirit.firstspirit.access.store.StoreElement;
import de.espirit.firstspirit.access.store.IDProvider;
import de.espirit.firstspirit.access.store.LockException;
import de.espirit.firstspirit.access.AccessUtil;
lang = context.getProject().getMasterLanguage();
// Selected section
targetSection = context.getStoreElement();
targetBody = targetSection.getParent();
targetPage = targetBody.getParent();
wasLocked = targetPage.isLocked();
try {
if(!wasLocked) {
targetPage.setLock(true, true);
}
targetSectionIndex = targetBody.getChildIndex(targetSection);
// Original section which will replace the current sectionReference
sourceSection = targetSection.getReference();
// Copy original section to targetBody
newSection = AccessUtil.copyStoreElement(sourceSection, targetBody);
// … and move to index of targetSection
targetBody.moveChild(newSection, targetSectionIndex);
// Remove targetSection from targetBody
targetBody.removeChild(targetSection);
// targetPage.release(); <--- funktioniert nicht
targetPage.setLock(false, true);
} catch(LockException lockFailed) {
context.logError("lock failed -> medium already locked by " + lockFailed.getUserLoginName());
} finally {
try {
if(!wasLocked) {
targetPage.setLock(false, true);
}
} catch(Exception unlockFailed) {
context.logError("unlock failed");
}
}
Und hier der Stacktrace der release()-Fehlermeldung:
FSVersion=4.2.446.45868#2542;JDK=1.6.0_31 32bit Apple Inc.;OS=Mac OS X 10.7.3 i386;Date=25.06.2012 14:53:30
de.espirit.firstspirit.access.script.ExecutionException: Method Invocation targetPage.release at line 45
at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:120)
at de.espirit.firstspirit.client.gui.applications.ApplicationTabRegistry$IdentifiableExecutable.execute(ApplicationTabRegistry.java:150)
at de.espirit.firstspirit.common.ScriptUtil.execute(ScriptUtil.java:88)
at de.espirit.firstspirit.client.action.ScriptMenuAction$ScriptAction.actionPerformed(ScriptMenuAction.java:222)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.AbstractButton.doClick(AbstractButton.java:389)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:809)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:850)
at java.awt.Component.processMouseEvent(Component.java:6375)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6140)
at java.awt.Container.processEvent(Container.java:2083)
at java.awt.Component.dispatchEventImpl(Component.java:4737)
at java.awt.Container.dispatchEventImpl(Container.java:2141)
at java.awt.Component.dispatchEvent(Component.java:4565)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
at java.awt.Container.dispatchEventImpl(Container.java:2127)
at java.awt.Window.dispatchEventImpl(Window.java:2482)
at java.awt.Component.dispatchEvent(Component.java:4565)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:684)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:643)
at java.awt.EventQueue$1.run(EventQueue.java:641)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:657)
at java.awt.EventQueue$2.run(EventQueue.java:655)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:654)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue.defaultDispatchEvent(AWTDispatchingEventQueue.java:130)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue._dispatchEvent(AWTDispatchingEventQueue.java:115)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue.dispatchEvent(AWTDispatchingEventQueue.java:108)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.lang.IllegalStateException: source section 'pressemeldungen' (ID=49507) of section reference 'Pressemeldungen' (ID=50379) is never released
at de.espirit.firstspirit.store.access.pagestore.PageImpl.checkRelease(PageImpl.java:571)
at de.espirit.firstspirit.store.access.DefaultStoreElement.release(DefaultStoreElement.java:582)
at de.espirit.firstspirit.store.access.DefaultStoreElement.release(DefaultStoreElement.java:542)
at de.espirit.firstspirit.store.access.AbstractStoreElement.release(AbstractStoreElement.java:840)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at bsh.Reflect.invokeMethod(Unknown Source)
at bsh.Reflect.invokeObjectMethod(Unknown Source)
at bsh.Name.invokeMethod(Unknown Source)
at bsh.BSHMethodInvocation.eval(Unknown Source)
at bsh.BSHPrimaryExpression.eval(Unknown Source)
at bsh.BSHPrimaryExpression.eval(Unknown Source)
at bsh.BSHBlock.evalBlock(Unknown Source)
at bsh.BSHBlock.eval(Unknown Source)
at bsh.BSHBlock.eval(Unknown Source)
at bsh.BSHTryStatement.eval(Unknown Source)
at bsh.BSHBlock.evalBlock(Unknown Source)
at bsh.BSHBlock.eval(Unknown Source)
at bsh.BshMethod.invokeImpl(Unknown Source)
at bsh.BshMethod.invoke(Unknown Source)
at bsh.BshMethod.invoke(Unknown Source)
at bsh.This.invokeMethod(Unknown Source)
at bsh.This.invokeMethod(Unknown Source)
at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:111)
... 44 more
Sie müssen erst entsperren und dann das Element freigeben.
Das Problem taucht weiter unter im Stacktrace auf:
"Caused by: java.lang.IllegalStateException: source section 'pressemeldungen' (ID=49507) of section reference 'Pressemeldungen' (ID=50379) is never released"
Der ursprüngliche Absatz mit der ID 49507 ist noch nicht im Freigabestand verfügbar, wurde also noch nie freigegeben.
Sie meinen erst setLock(false, true) und dann release()? Dann bekomme ich diesen Fehler:
…Caused by: java.lang.IllegalStateException: unable to release node 'drgffdgfd' (ID=49992) - not locked
Anders herum (erst release(), dann setLock()) kein Fehler, aber gleiches Verhalten.
Ich versteh gerade den Zusammenhang zu freigegeben oder nicht nicht ganz. Ich möchte dem Benutzer erlauben, unabhängig von diesen Umständen Absatzreferenzen zu überschreiben (was ja – ohne Freigabe etc. – auch funktioniert, wenn ich jedes mal den Bearbeitungsmodus manuell verlasse).
Edit: das setLock(), release() oben ist denke ich sowieso überflüssig, an sich müsste ja das setLock im finally-Block reichen (ein Löschen ändert aber nichts).
Das war mein Fehler. Sie geben ja auf dem Client frei, da müssen Sie in der Tat einen Lock auf dem Objekt haben, bevor Sie den Knoten freigeben können. Ihre erste Version war also bereits korrekt.
Wenn Sie den Knoten nicht freigeben wollen, können sie sich das release() in der Tat sparen.
Welcher Fehler kommt, wenn Sie das release() weglassen?
Es kommt gar kein Fehler, es taucht nur immer das im ersten Post beschriebene Phänomen auf (vorher überschriebene Absatz-Referenzen sind auf einmal wieder da, wenn man den Bearbeitungsmodus nicht jedes Mal verlässt).
Ich bin nicht sicher, ob die move/remove Operationen auch implizit speichern.
Eventuell hilft also ein targetPage.save() nach den Operationen.