How to create a directory on the basis of path in cq5? - aem

I have a String which is the path of the page for example /content/xperia/public/events/eventeditor. I am gererating the XML of this page and saving it to DAM, but I want to save it in the similar tree structure under /content.
I tried the following code
String page = "/content/xperia/public/events/eventeditor";
page = page.replace("/content", "/content/dam");
if (adminSession.nodeExists(page+ "/"+ "jcr:content")) {
Node node = adminSession.getNode(page+ "/"+ "jcr:content");
node.setProperty("jcr:data", sb.toString());
} else {
Node feedNode = JcrUtil.createPath(page,"nt:file", adminSession);
Node dataNode = JcrUtil.createPath(feedNode.getPath() + "/"+ "jcr:content", "nt:resource", adminSession);
dataNode.setProperty("jcr:data",sb.toString());
}
But it gives the following error
No matching child node definition found for
{http://www.jcp.org/jcr/1.0}content
Because there is no such path in the repository. Is there a way through which I can create a directory on the fly. Because to save this file, I need to create the entire tree xperia/public/events under /content/dam and then save eventeditor.xml in that directory .
Please suggest.

There are a few issues with your code. The JcrUtil.createPath(String absolutePath, String nodeType, Session session) creates all the non-existent intermediate path with the given NodeType.
This means that all the nodes xperia, public and events are created with type nt:file instead of sling:OrderedFolder.
You can use the createPath(String absolutePath, boolean createUniqueLeaf, String intermediateNodeType, String nodeType, Session session, boolean autoSave) method instead, to specify the type of intermediary nodes that are to be created.
String page = "/content/xperia/public/events/eventeditor";
page = page.replace("/content", "/content/dam");
page += ".xml";
if (adminSession.nodeExists(page+ "/"+ "jcr:content")) {
Node node = adminSession.getNode(page+ "/"+ "jcr:content");
node.setProperty("jcr:data", sb.toString());
} else {
Node feedNode = JcrUtil.createPath(page, true, "sling:OrderedFolder", "nt:file", adminSession, false);
Node dataNode = feedNode.addNode("jcr:content", "nt:resource");
dataNode.setProperty("jcr:data",sb.toString());
}
adminSession.save();

Related

How does the next object work in Linked List? How is it able to make another class objects point to the next address?

class Node
{
public int data;
public Node next;
public Node(int idata) {
data = idata;
next = null;
}
}
Node newnode = new Node(val);
newnode.next = null;
Like if I'm creating a new object newnode of the class Node , how is it able to use .next to find the next address of the list?
In your example code next is just null. Actually, it was not necessary to explicitly do newnode.next = null;, as it already was initialised to null in the Node constructor.
It becomes more interesting when you assign another new node to the next property of the node you have created:
Node newnode = new Node(1);
newnode.next = new Node(2);
In Java objects are accessed with references. newnode is such a reference, and newnode.next is also such a reference. Both are references to Node instances (if not null).
We could extend the linked list further:
newnode.next.next = new Node(3);
newnode.next.next.next = new Node(4);
When you realise that next is a property that can hold a value like any variable, then there is really no magic to it.
You could for instance also first create Node instances that are disconnected, and only after their creation link them together:
Node a = new Node(1);
Node b = new Node(2);
Node c = new Node(3);
Node d = new Node(4);
a.next = b;
b.next = c;
c.next = d;

How-to get the code for downloading metadata along with images in IBM content manager

I am trying to find the code in java API which works with cm IBM.. the sample code is there but it is just for logging in.. can anyone help to get the code to download the images along with metadata
as you said you have basic connection code, use the below function to download the document..
public String retrieveDocument(CMBConnection connection, CMBItem item)
throws CMBException, IOException, Exception
{
// Get an instance of data management bean
CMBDataManagement dataManagement = connection.getDataManagement();
// Set the current data item
dataManagement.setDataObject(item);
// Retrieve the original file name
CMBObject object = dataManagement.getContent(0);
String inputFileName = object.getOriginalFileName();
// Parse the file name from the full path
int pos=inputFileName.lastIndexOf("\\");
inputFileName = inputFileName.substring(pos+1);
// Write the document content to a new file
String fileName = System.getProperty("user.dir")
+ File.separator + inputFileName;
System.out.println("Output file name " + fileName);
FileOutputStream fileoutstream = new FileOutputStream(fileName);
fileoutstream.write(dataManagement.getContent(0).getData());
fileoutstream.close();
// Return file name
return fileName;
}

How to find unused images from CQ DAM

Is there a way to find to unused assets from CQ DAM? Currently our CQ instance has accumulated huge amount of assets and at least 25% is not being used as of now. Our CQ instance is running on windows (5.6). Is there a cleaner way to do the same?
Thanks,
Santhosh
You may use the following XPATH query to get all assets:
/jcr:root/content/dam//*[#jcr:primaryType='dam:Asset']
Using QueryManger you may get list of asset nodes:
Workspace workspace = session.getWorkspace();
QueryManager qm = workspace.getQueryManager();
Query query = qm.createQuery(xpathQuery, Query.XPATH);
QueryResult queryResult = query.execute();
result = queryResult.getNodes();
Next you need to get path of every asset and verify is it used:
while(result.hasNext()) {
Node assetNode = result.nextNode();
String assetPath = assetNode.getPath();
}
To verify is it asset used you need again run xpath :
/jcr:root/content/mywebsite//*[#fileReference='putAssetPathHere']
Now result.hasNext() == true means asset is used
Another solution is to use ReferenceSearch
for (String path : paths) {
if (resourceResolver.getResource(path) != null) {
Map<String, ReferenceSearch.Info> searchResult = referenceSearch.search(resourceResolver, path);
if (searchResult.isEmpty()) {
//path is unused asset
}
//get used pages
for (Map.Entry<String, ReferenceSearch.Info> info : searchResult.entrySet()) {
info.getKey();//will return page path
}
//get used properties paths
for (Map.Entry<String, ReferenceSearch.Info> info : searchResult.entrySet()) {
for (String prop : info.getValue().getProperties()) {
//prop is property path
}
}
}
}
For me following code worked.
help link : http://wemcode.wemblog.com/get_asset_reference_in_page
String damPath = "/content/dam/geometrixx/offices/basel kitchen.jpg";
for (ReferenceSearch.Info info: new ReferenceSearch().search(resourceResolver, damPath).values()) {
for (String p: info.getProperties()) {
out.println("Path is "+info.getPage().getPath());
}

Nodes added to a page are not being saved in CQ

I have a service that's attempting to import blog pages into CQ 5.5.0. I am able to successfully create the page, but when I add nodes representing the content the nodes are not being saved. No errors are reported by CQ and I can see the nodes in the service immediately after creation. But when I look at the page in CRXDE Light the nodes are not part of the page content. The section of code that adds the nodes is here:
Node blogNode = blogPage.adaptTo(Node.class);
logOutput( INFO, "blogPage name = "+ blogPage.getName() );
// Create the author date node
Node authorDateNode = blogNode.addNode("jcr:content/authorDate", "nt:unstructured");
authorDateNode.setProperty("author", blog.getCreator());
authorDateNode.setProperty("date", sdf.format(blog.getPublishDate().getTime()));
authorDateNode.setProperty("sling:resourceType", "history/components/blog/authordate");
// Create the content node
Node blogPostNode = blogNode.addNode("jcr:content/blogPostBodyParSys", "nt:unstructured");
blogPostNode.setProperty("sling:resourceType", "history/components/parsys");
Node blogContentNode = blogNode.addNode("jcr:content/blogPostBodyParSys/text", "nt:unstructured");
blogContentNode.setProperty("sling:resourceType", "history/components/text");
blogContentNode.setProperty("text", blog.getContent());
blogContentNode.setProperty("textIsRich", "true");
// TODO: Test code only
NodeIterator itr = blogNode.getNode("jcr:content").getNodes();
while(itr.hasNext()) {
Node child = itr.nextNode();
logOutput(INFO, "Child node: " + child.getName(), 1 );
PropertyIterator propItr = child.getProperties();
while( propItr.hasNext() ) {
Property prop = propItr.nextProperty();
logOutput(INFO, "Property " + prop.getName() + ", value " + prop.getValue().getString(),2);
}
}
The test code at the bottom displays the newly created nodes and it shows values as expected. The last thing that occurs is a call to 'session.save' before the service exits.
No errors are reported but I do not see the nodes when I look at the page. Does anyone have any idea about what might be wrong here?
As pointed by #Sharath Maddapa you need to save the session. See the changes done in your code.
Node blogNode = blogPage.adaptTo(Node.class);
logOutput( INFO, "blogPage name = "+ blogPage.getName() );
// Create the author date node
Node authorDateNode = blogNode.addNode("jcr:content/authorDate", "nt:unstructured");
authorDateNode.setProperty("author", blog.getCreator());
authorDateNode.setProperty("date", sdf.format(blog.getPublishDate().getTime()));
authorDateNode.setProperty("sling:resourceType", "history/components/blog/authordate");
// Create the content node
Node blogPostNode = blogNode.addNode("jcr:content/blogPostBodyParSys", "nt:unstructured");
blogPostNode.setProperty("sling:resourceType", "history/components/parsys");
Node blogContentNode = blogNode.addNode("jcr:content/blogPostBodyParSys/text", "nt:unstructured");
blogContentNode.setProperty("sling:resourceType", "history/components/text");
blogContentNode.setProperty("text", blog.getContent());
blogContentNode.setProperty("textIsRich", "true");
//YOU must save the session here.
try {
blogNode.getSession().save();
} catch(Exception e) {// TODO Ideally log specific exceptions
logOutput( ERROR, "Error saving jcr session ");
}
// TODO: Test code only
NodeIterator itr = blogNode.getNode("jcr:content").getNodes();
while(itr.hasNext()) {
Node child = itr.nextNode();
logOutput(INFO, "Child node: " + child.getName(), 1 );
PropertyIterator propItr = child.getProperties();
while( propItr.hasNext() ) {
Property prop = propItr.nextProperty();
logOutput(INFO, "Property " + prop.getName() + ", value " + prop.getValue().getString(),2);
}
}
I appreciate the input and I finally figured out what was causing my problem: I had created two ResourceResolver instances so the session I was saving was apparently a different session from where the nodes were being created. And that session was not being saved.

dynamic connection string with EF4, get metadata path is not valid

Here is my problem.
I use a dynamic connection string for my Entity Framework context.
//In Web Config
add key="DataSource" value="WIN-QBRH0MJL8IT\ISS" />
//In my EntityFactory.cs
public static DBEntities GetEntity()
{
var scsb = new SqlConnectionStringBuilder();
scsb.DataSource = ConfigurationManager.AppSettings["DataSource"];
scsb.InitialCatalog = "db1";
scsb.MultipleActiveResultSets = true;
scsb.IntegratedSecurity = true;
if (HttpContext.Current.Session["DBName"] == null)
{
HttpContext.Current.Response.Redirect("/Account/Step1");
}
else
{
scsb.InitialCatalog = HttpContext.Current.Session["DBName"].ToString();
}
var builder = new EntityConnectionStringBuilder();
builder.Metadata = "metadata=~/bin/Models/DBModel.csdl|~/bin/Models/DBModel.ssdl|~/bin/Models/DBModel.msl";
builder.Provider = "System.Data.SqlClient";
builder.ProviderConnectionString = scsb.ConnectionString;
DBEntities db = new DBEntities(builder.ConnectionString);
return db;
}
I Know the problem is for this line :
builder.Metadata =
"metadata=~/bin/Models/DBModel.csdl|~/bin/Models/DBModel.ssdl|~/bin/Models/DBModel.msl";
I check and the csdl, ssdl, msl are in /mvcinfosite/bin/Models/.csdl,.ssdl,.msl
The configuration for my edmx is:
Metadata Artifact Processing : Copy to Output Directory
Here is the full error
The specified metadata path is not valid. A valid path must be either
an existing directory, an existing file with extension '.csdl',
'.ssdl', or '.msl', or a URI that identifies an embedded resources
Thanks
Try to remove ~ character and use valid relative path to your app root. I think it is not able to work with this special character used on in ASP.NET application.