How to work with entities

broszeit
I'm new here
7 3 3,857


Working with FirstSpirit often also means working with data sources (Content2-objects). In general the data of the data sources can be managed by using the FirstSpirit UI. But to change large sets of data or to import data from an external source, you have to know how to create, read, update and delete data records (entities) in FirstSpirit data sources by using the API.

In this blogposting you will get an explanation how to work with data sources and how to set or change the data of their data records.

We will have a look at the code step by step. The specific code blocks are divided logically (as far as possible). For specific explanations of the code have a look at the inline-comments.


Create

Let’s start with creating a press release in the “Mithras Energy” demo project.

A press release consists of a headline, a subheadline, a teaser, a date and a content-block, which has its own headline and text.

We want to set the contents of those fields as following:

        

           final String headline = "Important news";

           final String subheadline = "Short information";

           final String teaser = "Look out!!";

           final String date = "2012-02-21";

           final String contentHeadline = "Content Headline";

           final String contentText = "Content Text";

To create a data record (entity) with these values, we first of all need some objects.

We will get them in this code block:

// get the master language

LanguageAgent languageAgent = ((SpecialistsBroker) context).requireSpecialist(LanguageAgent.TYPE);

Language lang = languageAgent.getMasterLanguage();

// get the content- and the template-store

StoreAgent storeAgent = ((SpecialistsBroker) context).requireSpecialist(StoreAgent.TYPE);

ContentStoreRoot cs = (ContentStoreRoot) storeAgent.getStore(Store.Type.CONTENTSTORE);

TemplateStoreRoot ts = (TemplateStoreRoot) storeAgent.getStore(Store.Type.TEMPLATESTORE);

// get the ContentStore-element "pressreleases"

Content2 csPressreleases = (Content2) cs.getStoreElement("pressreleases", Content2.UID_TYPE);

// get the datasource schema and a session

Schema schema = csPressreleases.getSchema();

Session session = schema.getSession();

After that a new data record (entity) can be created. It has to be locked for the additional steps. 

// create a new entity

Entity entityPressrelease = session.createEntity(csPressreleases.getEntityType().getName());

{

     try {

csPressreleases.lock(entityPressrelease);

Dataset dataSet = csPressreleases.getDataset(entityPressrelease);

                        FormData data = dataSet.getFormData();

We get a FormField from the FormData and set the values we defined above.


For CMS_INPUT_TEXT and CMS_INPUT_TEXTAREA:


// set the headline

data.get(lang, "cs_headline").set(headline);

// set the subheadline

data.get(lang, "cs_subheadline").set(subheadline);

// set the teaser

data.get(lang, "cs_teaser").set(teaser);

For CMS_INPUT_DATE:


// set the date

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

data.get(lang, "cs_date").set(sdf.parse(date));


Now we have a form with a FS_LIST which contains paragraphs. To fill in a FS_LIST we need the following code:


// FS-List

FormField ff = data.get(lang, "cs_content");  //cs_content is the FS_LIST

FormDataList dataList = (FormDataList) ff.get();

           

All paragraphs inside the FS_LIST have the uid "textpicture". So we create an IdProvidingFormData-object based on this template.


//create FormData with a section template

SectionFormsProducer producer = (SectionFormsProducer) dataList.getProducer();

IdProvidingFormData sectionFormData = producer.create(ts.getSectionTemplates().getTemplate("textpicture"));


// just add content into this paragraph as above:

formData.get(lang, "st_headline").set(contentHeadline);

 
In addition to the headline the paragraph inside the FS_LIST contains a CMS_INPUT_DOM, which can be filled as easy as the FormFields above:

// DOM in FS-List

// get and set the FormField

FormField dom = sectionFormData.get(lang, "st_text");

dom.set(contentText);

Don’t forget to add the FormData to the FS_List:


// add sectionFormData to theFS_LIST

dataList.add(sectionFormData);

ff.set(dataList);

In the last step we are going to save the FormData and unlock the data record (entity):

(The save-command in the following block triggers a commit at the session. If you work with just one entity - like in this example - that is the right way. But if you work with a lot of entities you should not use the save-command and should make a cyclic commit instead.)

// set FormData and save the dataSet

dataSet.setFormData(data);

dataSet.save();

          } catch (Exception ex) {

                      ex.printStackTrace();

          } finally {

                        try {

                                   csPressreleases.unlock(entityPressrelease);                                                               

                        } catch (Exception e) {

                                   System.out.println("FATAL!");

                        }

            }

    }

Update

Updating a data record (entity) includes nearly the same steps as creating one:

     1) Get the Content2 objects

     2) Get the entity and the FormData

     3) Change the FormData

     4) Save the changes

The first step is exactly the same as we have seen above.


But instead of creating a new data record (entity), we got it now in the second step from the data source (Content2-object). Therefore you need the ID of the entity:

   

    // get entity from datasource

     final Long entityId = 128L; // the id of the entity you are working with

     Entity entityPressrelease = session.find(csPressreleases.getEntityType().getName(), entityId);

Now we can work with this data record (entity) and get its DataSet and FormData.

   

     Dataset dataSet = csPressreleases.getDataset(entityPressrelease);

     FormData data = dataSet.getFormData();

We change our FormData the same way as before.


For example change the headline by adding some new text to the existing headline:


// add the headline

FormField formField = data.get(lang, "cs_headline");

formField.set(formField.get() + addHeadline);

It’s the same for the date, the subheadline and any other field.

Just the FS_LIST needs more attention again.

We use an IdProidingFormData-object to get the FS_LIST-data:

 

// FS-List

FormField ff = data.get(lang, "cs_content"); //cs_content is the FS_LIST
FormDataList dataList = (FormDataList) ff.get();

IdProvidingFormData formData = dataList.get(0);

Changing the headline is very simple again:


       // just add content into this paragraph as above:

       formField = formData.get(lang, "st_headline");

       formField.set(formField.get() + addContentHeadline);

 
Changing the DOM works as following:

        // BEGIN DOM in FS-List

               // just get and set the FormField like before

         DomElement dom = (DomElement) formData.get(lang, "st_text").get();

         String text = "" + dom.toText(false); //reads the existing text

         dom.set(text + addContentText); // adds the new to the old text

      

        // END DOM

The difference between creating and updating this element is that we just change the existing element instead of adding a new one to the FS_LIST.

In this case we only neet to get the text of each FormField, add our new text and replace the old text by the new one.

Finally add the changed data to our FS_LIST:


// add the FormDataList in the FS_LIST

       ff.set(dataList);

... and save everything:


// set FormData and save the dataSet

       dataSet.setFormData(data);

       dataSet.save();

 

Delete

The last explanation is how to delete data records (entities).

Deleting a data record (entity) includes nearly the same steps as updating one:

1) Get the Content2 object

2) Get the entity

3) Delete the entity

4) Commit the changes

Again the first step is the same as in the two examples above.

For step two we need to get the data record (entity) from the data source (Content2-object). Therefor you can use the same code as in the previous updating-example.

Instead of updating the data record (entity) it is now marked as deleted by using the method delete():

  // delete the database entity

   session.delete(entityPressrelease);

To make this deletion persistent the modification has to be committed with the method commit():

    // commit the modifications

  session.commit();

That’s it. The data record (entity) is removed and doesn’t exist anymore.

With these three examples you now have the ability to create, update and delete data records (entities).

Further steps

For those of you who want to expand their code blocks we have additional methods, which are also very useful.

  If you want to release the entity at the end of the script just add:

     csPressreleases.release(entityPressrelease);

The Content2-object csPressreleases we already got in the first step at the beginning of the script with the following call:

     // get the content-store-element "pressreleases"
     Content2 csPressreleases = (Content2) cs.getStoreElement("pressreleases", Content2.UID_TYPE.CONTENTSTORE);

If you want to get a confirmation dialog in case of success just call:

     // show a confirmation dialog in case of succees
     // get operationAgent
     OperationAgent operationAgent = context.requireSpecialist(OperationAgent.TYPE);

     // success message
     RequestOperation requestOperation = operationAgent.getOperation(RequestOperation.Type);
     requestOperation.setKind(RequestOperation.Kind.INFO);    
     requestOperation.setTitle("Success");    
     requestOperation.perform("Pressrelease successfully deleted.");

Get the sourcecode, build the module and create the scripts

Get the sourcecode

The complete sourcecode of the described examples can be downloaded via a GitHub-Repository, which you can find here. The package "com.espirit.moddev.knowledgebase" contains the classes for creating, updating and deleting a data record (entity) inside a FirstSpirit-datasource (Content2-object).

To make these classes available in your FirstSpirit-project you need to build a module, install it at your FirstSpirit-server and create three scripts inside your FirstSpirit-project.

Build the module

Next to the sourcecode the GitHub-Repository contains a "pom.xml". With using Maven it is possible to build a new module based on this file.

(If you first need to install Maven, follow the instructions here.)

For a successful compilation of the sourcecode it is necessary to install the "fs-access.jar"-file of the FirstSpirit-server in the local Maven-Repository. (The local Maven-Repository was created automatically while the Maven-installation. It can be find under ${user.home}/.m2/repository.)The "fs-access.jar"-file is located under the directory <FS-Server-Folder>/data/fslib.

The following command will trigger the installation:

mvn install:install-file -Dfile=<path-to-acces.jar> -DgroupId=de.espirit.firstspirit -DartifactId=fs-access -Dversion=<fs version e.g. '5.0.0'> -Dpackaging=jar

Within this command the path to the "fs-acces.jar"-file has to be replaced.

After the installation of the "fs-access.jar"-file to the Maven-Repository the new module can be build with this command:

mvn package -Dci.version=<version> -Dfirstspirit.version=<fs-version>

Within this command the "version" and the the "fs-version" has to be replaced. The "fs-version" has to be the same as the "Dversion" in the previous command.

Install the module

At the directory of the pom.xml a new subfolder "target" will be created. This folder contains the new module, which has to be installed at the FirstSpirit-server. Therefore open the server-properties inside the server- and projectconfiguration and choose the menu item "Modules" to install the fsm-file by clicking the button "Install". After the installation of the module its files are available for all projects on this server.

Create the scripts

To use the code of the examples inside a project, three scripts are needed for creating, updating and deleting a data record (entity).

Each of these scripts has just two lines, which contain the command to call one of the classes inside the module.

Note:

The updating and deleting class inside the module use hardcoded ids of two data records inside the Mithras-datasource "pressreleases"! So the examples just work with a Mithras-demoproject.

After running the deletion-script the data record and its id won't exist anymore. If the deletion-script should be used futher times, the deleted data record has to be restored each time.

create-script:

#!executable-class

com.espirit.moddev.knowledgebase.Content2ExampleExecutable_Create

update-script:

#!executable-class

com.espirit.moddev.knowledgebase.Content2ExampleExecutable_Update

delete-script:

#!executable-class

com.espirit.moddev.knowledgebase.Content2ExampleExecutable_Delete

Be assured your scripts have the type "Context menu" so you can execute them from inside the context menu.

1.png

Last words

Scripting with FirstSpirit might seem difficult and complex at the beginning but you will learn it soon. Don’t worry if you don’t understand some parts of the shown code. You’ll often be able to use structures and parts code you already wrote. At the beginning it might be the easiest way to have a look at existing code and modify it until it fits your needs.


This tutorial could be a help if you are writing your first scripts or if you want to create a database entry with the help of a script. Of course there are many different solutions for this task, but this could be a help for the first orientation.

You should know that it will take some time to get comfortable with the FirstSpirit API.

Don’t forget: The easiest way to get comfortable with the API is to write your own code.


So have a try!


3 Comments