Based on the documentation here we can see that in a xwiki java extension, we can intercept the event UserCreation like that :
https://extensions.xwiki.org/xwiki/bin/view/Extension/Observation%20Module%20Local#HWritinganEventListenerinVelocityinaWikipage
public void onEvent(Event event, Object source, Object data)
{
XWikiDocument document = (XWikiDocument) source;
String wikiName = document.getDocumentReference().getWikiReference().getName();
DocumentReference userClass = new DocumentReference(wikiName, "XWiki", "XWikiUsers");
if (document.getXObject(userClass) != null) {
}
I want the same thing, but I want to detect the event space creation ( so basically when you add a space( basically a space is the main root page of an article ) in your wiki. But I didn't found any class like XWikiUsers for the space or the page.
It don't want to do it with velocity or groovy but in pure java extension and I have no clue, the doc is very huge but it's hard to found what I' looking for.
Technically, a "space" gets created whenever a page is created under it (either terminal page or WebHome).
So you could either:
do a query each time a page is being created (DocumentCreatingEvent, so not yet DocumentCreatedEvent) and then do a query (see https://extensions.xwiki.org/xwiki/bin/view/Extension/Query%20Module) to see if the space (matching the new document's space reference) matches an existing one or a deeper nested one inside the database... or
check if the newly created document (DocumentCreatedEvent) has the name WebHome which would be much better in terms of performance, but it will not work if you are working with terminal documents (i.e. other documents than 'WebHome' ones, see https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/ContentOrganization/#HTerminology
Related
I want to update a document with a User object that I have, but I do not want the document to be created if it does not exist, and therefore I cannot use "DocumentReference.set" with "SetOptions.Merge()" (to my understanding).
However, according to this post (Difference between set with {merge: true} and update), "update" is actually the command I need. My problem is, it doesn't seem like update accepts a Java object.
I do not want to check whether or not the document exists myself, as this will result in an unnecessary read.
Is there any way around this?
Here is my code (I have removed success and failure listeners for simplicity):
public void saveUser(User user)
{
CollectionReference collection = db.collection("users");
String id = user.getId();
if (id.equals(""))
{
collection.add(user);
}
else
{
// I need to ensure that the ID variable for my user corresponds
// with an existing ID, as I do not want a new ID to be generated by
// my Java code (all IDs should be generated by Firestore auto-ID)
collection.document(ID).set(user);
}
}
It sounds like you:
Want to update an existing document
Are unsure if it already exists
Are unwilling to read the document to see if it exists
If this is the case, simply call update() and let it fail if the document doesn't exist. It won't crash your app. Simply attach an error listener to the task it returns, and decide what you want to do if it fails.
However you will need to construct a Map of fields and values to update using the source object you have. There are no workarounds for that.
Given a starting path I want to create a tree like object representing the filesystem using Java, showing all the folders down to level x but not ordinary files. . So using FileVisitor I know that every time just before Im going to browse a new subfolder that the preVisitDirectory() method will be called and once it had completed parsing all its children the postVisitDirectory() will be called, but my problem is knowing how to attach this directory to its parent.
i.e in my case I want to create data for jstree using ul/li/ul/li elements, and Im doing this with j2html lib. So create root using ul(), then when I go into preVisitDirectory() I would create a li() element and in postVisitDirectory() would want to attach to ul() using ul().with(li) but I cant see how to keep track of where I am in building my tree.
e.g static hard coded example not actually browsing tree
public Tag createBrowseTreeAsHtml()
{
Tag ulTag = ul(
li("ChildNode 2").withId("child_node_1"),
li("ChildNode")
);
Tag divTag= div(
ul(
li("Root Node 1").with(ulTag),
li("Root Node 2")
)
)
.withId("jstree");
return div().with(divTag);
}
I see Guava has support for Graphs, should I be utilising this somehow ?
I want to create a plugin that adds a video on the current slide in an open instance of Open Office Impress by specifying the location of the video automatically. I have successfully added shapes to the slide. But I cannot find a way to embed a video.
Using the .uno:InsertAVMedia I can take user input to choose a file and it works. How do I want to specify the location of the file programmatically?
CONCLUSION:
This is not supported by the API. Images and audio can be inserted without user intervention but videos cannot be done this way. Hope this feature is released in subsequent versions.
You requested information about an extension, even though the code you are using is quite different, using a file stream reader and POI.
If you really do want to develop an extension, then start with one of the Java samples. An example that uses Impress is https://wiki.openoffice.org/wiki/File:SDraw.zip.
Inserting videos into an Impress presentation can be difficult. First be sure you can get it to work manually. The most obvious way to do that seems to be Insert -> Media -> Audio or Video. However many people use links to files instead of actually embedding the file. See also https://ask.libreoffice.org/en/question/1898/how-to-embed-video-into-impress-presentation/.
If embedding is working for your needs and you want to automate the embedding by using an extension (which seems to be what your question is asking), then there is a dispatcher method called InsertAVMedia that does this.
I do not know offhand what the parameters are for the call. See https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=61127 for how to look up parameters for dispatcher calls.
EDIT
Here is some Basic code that inserts a video.
sub insert_video
dim document as object
dim dispatcher as object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:InsertAVMedia", "", 0, Array())
end sub
From looking at InsertAVMedia in sfx.sdi, it seems that this call does not take any parameters.
EDIT 2
Sorry but InsertVideo and InsertImage do not take parameters either. From svx.sdi it looks like the following calls take parameters of some sort: InsertGalleryPic, InsertGraphic, InsertObject, InsertPlugin, AVMediaToolBox.
However according to https://wiki.openoffice.org/wiki/Documentation/OOoAuthors_User_Manual/Getting_Started/Sometimes_the_macro_recorder_fails, it is not possible to specify a file for InsertObject. That documentation also mentions that you never know what will work until you try it.
InsertGraphic takes a FileName parameter, so I would think that should work.
It is possible to add an XPlayer on the current slide. It looks like this will allow you to play a video, and you can specify the file's URL automatically.
Here is an example using createPlayer: https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=57699.
EDIT:
This Basic code works on my system. To play the video, simply call the routine.
sub play_video
If Video_flag = 0 Then
video =converttoURL( _
"C:\Users\JimStandard\Downloads\H264_test1_Talkinghead_avi_480x360.avi")
Video_flag = 1
'for windows:
oManager = CreateUnoService("com.sun.star.media.Manager_DirectX")
' for Linux
' oManager = CreateUnoService("com.sun.star.media.Manager_GStreamer")
oPlayer = oManager.createPlayer( video )
' oPlayer.CreatePlayerwindow(array()) ' crashes?
'oPlayer.setRate(1.1)
oPlayer.setPlaybackLoop(False)
oPlayer.setMediaTime(0.0)
oPlayer.setVolumeDB(GetSoundVolume())
oPlayer.start() ' Lecture
Player_flag = 1
Else
oPlayer.start() ' Lecture
Player_flag = 1
End If
End Sub
This one seems like it should be simple enough. I'm writing a Notes Agent in Java; it calculates a fairly large amount of numeric data (a 6400-entry array of doubles) that I want to store in an existing document, updating a field. Because of Notes' field limitations, I figured I needed to use a RichText field to do that. (My initial attempt to write to a multi-value Number field resulted in it failing to save somewhere between an array of size 4000 and 5000.) It's not clear to me how one stores that value in a RichTextItem, though. All my attempts have failed. In one case, using doc.replaceItemValue(), it seemed to convert the item to a Text List. Getting the item, casting it to a RichTextItem, and calling setValues() or setValueString() doesn't seem to do anything. This shouldn't be this hard! Any pointers?
(Alternately: Any better suggestion for how to store my array in a document in the database?)
Thanks,
Reid
You'll need to create a RichTextItem and use the methods on that object to populate it:
import lotus.domino.*;
import java.util.Vector;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
// (Your code goes here)
Database db = agentContext.getCurrentDatabase();
Document doc = db.createDocument();
Item subject = doc.replaceItemValue("Subject",
"Project description");
RichTextItem body = doc.createRichTextItem("Body");
body.appendText("Cartoon book for children
ages 9-12");
// Print text of subject and body
System.out.println(subject.getText());
System.out.println(body.getText());
// Save the document
doc.save(true, true);
} catch(Exception e) {
e.printStackTrace();
}
}
}
UPDATE:
If you need to edit an existing document, instead of creating a new rich text item, you would get the existing one.
RichTextItem body = doc.GetFirstItem("Body"); // instead of createRichTextItem
You can bypass the Notes' field limitations. You can flag your item as «contains non-summary data» by using the NotesItem.IsSummary property. You need to set this property to false. But remember, you cannot use this item in views and folders.
Here is example:
Vector vector = new Vector();
for (int index = 0; index<6400;index++)
vector.addElement(new Double(Math.random()*100));
Item item = document.replaceItemValue("YourFieldName", vector);
item.setSummary(false);
document.save(true,true);
As for the question of "better" solution. I've recently written some code where I serialize/deserialize Java objects as JSON strings. This way they are well readable and easily restorable. I guess for the plain array it's a little problem. Especially if you do not want to restore it and have not interest to look at it (well, but probably it should be one or other :-)
And yes, you have to store it in the rich text anyway. Alternative you might write a text document and attach it in the RT field (again RT :-). Pretty usual scenario and easy to do.
Finally you could store data as database objects, but I guess from Java you do not really have access to do it. And it does not seem to be in any way better.
I am using a local database in my version of Lotus notes(8.5.2), and I am trying to get the data for two things:
The highlighted document/item in a NotesUIView
The document selected in a NotesUIDocument
However, all I get are the Notes URLs and I don't know what I should do with those. Can anyone help me out/throw me a breadcrumb?
P.S. Yes I am using the Java API for Eclipse.
Here is a code sample of what I do:
NotesUIWorkspace workSpace = new NotesUIWorkspace();
NotesUIElement currentElement = workSpace.getCurrentElement();
if (currentElement instanceof NotesUIView) {
NotesUIView currentView = (NotesUIView) currentElement;
NotesUIViewEntryCollection collection = currentView
.getActionableEntries();
Iterator docIterator = collection.documentIterator();
while (docIterator.hasNext()) {
NotesUIDocumentEntry entry = (NotesUIDocumentEntry) docIterator.next();
//I can't seem to get to the NoesUIDocument case like I can below... I want fields!
}
}
if(currentElement instanceof NotesUIDocument){
NotesUIDocument document = (NotesUIDocument) currentElement;
//Seem to be able to get the correct data fields only in this case!
document.getFields();
}
Fetching the "current" document is usually done via the NotesAgentContext.UnprocessedDocuments. In a view, that might return a collection of documents if the user as ticked several.
If you already have an NotesUIView, NotesUIView.getActionableEntries will give you the selected document(s).
When you have a NotesDocumentData instance, NotesUIWorkspace.openDocument can be used to open it up in edit mode. Then NotesUIWorkspace.getCurrentDocument can be used to get hold of the UI Document.
Notice that if you only want to read values from the document, it is more convenient to use the back-end classes like Document.
Have you got a URL as an example? If it includes the UUID of the document in question then you should be able to reference it directly with a getDocument(). Otherwise, the URL should include a view reference and a lookup key for that view in question.