-2

I am new to Adobe cq5. Went through many online blogs and tutorials but could not get much. Can any one provide a Adobe cq5 application example with detailed explanation that can store and retrieve data in JCR.

Thanks in advance.

Harish
  • 1
  • 1
  • 4
  • What online blogs have you read? What code have you tried by yourself ? You will need a basic understanding of the concepts behind CQ5(Sling, JCR, OSGi) before you start playing with JCR data. – Riju Mahna May 29 '13 at 07:46
  • http://helpx.adobe.com/adobe-cq/using/persisting-cq-data-java-content.html i have tried this but had problem in creating OSGI bundle. – Harish May 30 '13 at 07:22
  • I have used the JCR sample you mentioned. It worked perfectly. try this link on creating a simple bundle: http://dev.day.com/docs/en/cq/current/core/developing/development_tools/developing_with_crxde_lite.html#Managing%20a%20Bundle . You can create just a 'Hello world' bundle and display it by calling the method in your component jsp – Riju Mahna May 30 '13 at 08:35
  • hello world bundle works fine but when i try to compile the bundle in that link..it gives errors in the import statements of org.apache.felix.scr.annotations.Component;org.apache.felix.scr.annotations.Service;org.apache.felix.scr.annotations.Activate;org.apache.felix.scr.annotations.Reference;..like mentioned below.. Only a type can be imported. org.apache.felix.scr.annotations.Activate resolves to a package CustomerServiceImp.java /localhost_4502_cae88c4b-40f2-4421-9bc3-4facad55cfe1/WebContent/apps/com.sample.osgi.bundle/src/main/java/com/adobe/cq line 7 – Harish May 30 '13 at 11:18
  • hi riju, can u share me any good tutorials, from where u started to work on cq5... – Harish May 30 '13 at 12:41
  • I too got the same error and fixed by adding the below lines in the '.bnd' file Export-Package: * Import-Package: * Private-Package: * Make sure any other references to these 3 properties should be commented. After that, build the bundle again by right clicking on the .bnd file – Riju Mahna May 31 '13 at 11:17
  • I studied from dev.day.com only. – Riju Mahna May 31 '13 at 11:19
  • Sry riju,what did u mean by any other references to these 3 properties shoud be commented?can u eloborate pls... – Harish May 31 '13 at 16:06
  • I meant that these 3 properties should only have *as value. If they appear anywhere else in the .bnd file, comment them. Does it make sense ? – Riju Mahna Jun 01 '13 at 08:07
  • Hi riju, sorry for late reply. Thanks alot for that help. but i still have a problem. I have used getService method but I'm still getting null pointer exception while accessing the injestCustData method. – Harish Jun 10 '13 at 14:31

2 Answers2

2

Here's a snippet for CQ 5.4 to get you started. It inserts a content page and text (as a parsys) at an arbitrary position in the content hierarchy. The position is supplied by a workflow payload, but you could write something that runs from the command line and use any valid CRX path instead. The advantage of making it a process step is that you get a session established for you, and the navigation to the insert point has been taken care of.

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.jcr.Node;
import javax.jcr.RepositoryException;

import org.apache.sling.jcr.resource.JcrResourceConstants;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.exec.WorkflowData;
import com.day.cq.workflow.exec.WorkflowProcess;
import com.day.cq.workflow.metadata.MetaDataMap;

import com.day.cq.wcm.api.NameConstants;

@Component
@Service
@Properties({
        @Property(name = Constants.SERVICE_DESCRIPTION,
            value = "Makes a new tree of nodes, subordinate to the payload node, from the content of a file."),
        @Property(name = Constants.SERVICE_VENDOR, value = "Acme Coders, LLC"),
        @Property(name = "process.label", value = "Make new nodes from file")})
public class PageNodesFromFile implements WorkflowProcess {

    private static final Logger log = LoggerFactory.getLogger(PageNodesFromFile.class);
    private static final String TYPE_JCR_PATH = "JCR_PATH";

* * * 

    public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args)
            throws WorkflowException {

        //get the payload
        WorkflowData workflowData = workItem.getWorkflowData();
        if (!workflowData.getPayloadType().equals(TYPE_JCR_PATH)) {
            log.warn("unusable workflow payload type: " + workflowData.getPayloadType());
            workflowSession.terminateWorkflow(workItem.getWorkflow());
            return;
        }
        String payloadString = workflowData.getPayload().toString();

        //the text to be inserted
        String lipsum = "Lorem ipsum...";

        //set up some node info
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("d-MMM-yyyy-HH-mm-ss");
        String newRootNodeName = "demo-page-" + simpleDateFormat.format(new Date());
        SimpleDateFormat simpleDateFormatSpaces = new SimpleDateFormat("d MMM yyyy HH:mm:ss");
        String newRootNodeTitle = "Demo page: " + simpleDateFormatSpaces.format(new Date());

        //insert the nodes
        try {
            Node parentNode = (Node) workflowSession.getSession().getItem(payloadString);

            Node pageNode = parentNode.addNode(newRootNodeName);
            pageNode.setPrimaryType(NameConstants.NT_PAGE);                             //cq:Page

            Node contentNode = pageNode.addNode(Node.JCR_CONTENT);                      //jcr:content
            contentNode.setPrimaryType("cq:PageContent");                               //or use MigrationConstants.TYPE_CQ_PAGE_CONTENT
                                                                                        //from com.day.cq.compat.migration
            contentNode.setProperty(javax.jcr.Property.JCR_TITLE, newRootNodeTitle);    //jcr:title
            contentNode.setProperty(NameConstants.PN_TEMPLATE,
                    "/apps/geometrixx/templates/contentpage");                          //cq:template
            contentNode.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY,
                    "geometrixx/components/contentpage");                               //sling:resourceType

            Node parsysNode = contentNode.addNode("par");
            parsysNode.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY,
                    "foundation/components/parsys");

            Node textNode = parsysNode.addNode("text");
            textNode.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY,
                    "foundation/components/text");
            textNode.setProperty("text", lipsum);
            textNode.setProperty("textIsRich", true);

            workflowSession.getSession().save();
        }
        catch (RepositoryException e) {
            log.error(e.toString(), e);
            workflowSession.terminateWorkflow(workItem.getWorkflow());
            return;
        }
    }
}

I have posted further details and discussion.

A few other points:

  • I incorporated a timestamp into the name and title of the content page to be inserted. That way, you can run many code and test cycles without cleaning up your repository, and you know which test was the most recently run. Added bonus: no duplicate file names, no ambiguity.

  • Adobe and Day have been inconsistent about providing constants for property values, node types, and suchlike. I used the constants that I could find, and used literal strings elsewhere.

  • I did not fill in properties like the last-modified date. In code for production I would do so.

  • I found myself confused by Node.setPrimaryType() and Node.getPrimaryNodeType(). The two methods are only rough complements; the setter takes a string but the getter returns a NodeType with various info inside it.

  • In my original version of this code, I read the text to be inserted from a file, rather than just using the static string "Lorem ipsum..."

Once you've worked through this example, you should be able to use the Abobe docs to write code that reads data back from the CRX.

David Gorsline
  • 4,933
  • 12
  • 31
  • 36
2

If you want to learn how to write a CQ application that can store and query data from the CQ JRC, see this article:

http://scottsdigitalcommunity.blogspot.ca/2013/02/querying-adobe-experience-manager-data.html

This provides a step by step guide and walks you right through the entire processes - including building the OSGi bundle using Maven.

FRom the comments above - I see reference to BND file. You should stay away from CRXDE to create OSGi and use Maven.

smac2020
  • 9,637
  • 4
  • 24
  • 38