Query builder API in Cq5 - aem

Hi I am implementing a Java module to fetch the pages which has a particular component.
Below is the code snippet which i use, but when running the module am getting an warning Saying that no PredicateEvaluator found for 'sling:resourceType'.
Kindly suggest me the proper way to give resourceType property as query parameter
Map<String, String> predicateMap = new HashMap<String, String>();
predicateMap.put("path","/content/geometrixx-outdoors/en/men");
predicateMap.put("type", "cq:Page");
predicateMap.put("sling:resourceType", "geometrixx-outdoors/components/title");
predicateMap.put("p.limit", "-1");
QueryBuilder queryBuilder = slingScriptHelper.getService(QueryBuilder.class);
com.day.cq.search.Query queryObj = queryBuilder.createQuery(PredicateGroup.create(predicateMap), session);

sling:resourceType is indeed not a valid predicate evaluator. You need to put it as a property:
predicateMap.put("property", "jcr:content/sling:resourceType");
predicateMap.put("property.value", "geometrixx-outdoors/components/title");
As you alre filtering type=cq:Page you have to also include jcr:content in the path to the property.

Related

How to set custom object in body of message in cxf?

I have a REST webservice with method custom (GET).
#GET
#Path("/custom")
public UIResponse custom(final UIParameters uiParameters){...}
As you can see this method has one argument. This is my custom object.
Object UIParameters is built from argument given as query string.
eg. http://example.com/custom?objectType=article
UIParameters object will contain one field:
UIParameters {
String objectType = "article";
}
I have tried to use InInterceptor to get this parameter from URL, build UIParameter object and set Content of message. Unfortunatelly it doesn't work.
After that I've provide MessageBodyReader for UIParameters but it still doesn't work.
What should I do to achive this goal?
Thanks
Update:
In InInterceptor I've copied query string to http headers. Now part of URL where user place parameters is accessible in my MessageBodyReader. Here I can build my object UIParameters.
Everything works fine but I don't think that this solution is the best.
Does somebody know better solution?
AnnotationQueryParam("") allows to get all the query parameters injected.
You do not need an interceptor and it is not the recommended way. See CXF documentation http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Parameterbeans
#GET
#Path("/custom")
public UIResponse custom(#QueryParam("") UIParameters uiParameters)
class UIParameters {
String objectType;
}
If you want to build the bean yourself using the query parameters use #Context UriInfo annotation
#GET
#Path("/custom")
public UIResponse custom( #Context UriInfo uriInfo){
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
new UIParameters().Builder()
.objectType(params.getFirst("type"))
.build();
}

Sling process child resources

Is there a way to access properties of a child resource using Sling API ? I know with JCR API it is possible to access child nodes. Sling does give a way to list Children. But
Resource pageResource = resolver.getResource("/content/sitename/page/jcr:content");
ModifiableValueMap map = pageResource.adaptTo(ModifiableValueMap.class);
map.put("component01/propertyName","Changed Text");
doesn't work. This throws an 'Invalid Property' SlingException. Any suggestions ?
doesn't work. This throws an 'Invalid Property' SlingException.
The quotes (“”) seem to be little fishy as I mentioned in the comment.
Try the following snippet .
You can fiddle around with these kind of requirements with the beautiful AEM Fiddle by ACS Tools.
Resource pageResource = resourceResolver.getResource("/content/sitename/page/jcr:content");
Iterable<Resource> childrenResources = pageResource.getChildren(); // Gives you all the resources representing direct children of /content/sitename/page/jcr:content
for(Resource childResource : childrenResources){
ModifiableValueMap mValueMap = childResource.adaptTo(ModifiableValueMap.class); // childResource should represent "component01" .
mValueMap.put("someProperty", "Some Value");
}

How to set a resource property

I have a Sling Resource object. What is the best way to set or update its property?
It depends on the Sling version:
Sling >= 2.3.0 (since CQ 5.6)
Adapt your resource to ModifiableValueMap, use its put method and commit the resource resolver:
ModifiableValueMap map = resource.adaptTo(ModifiableValueMap.class);
map.put("property", "value");
resource.getResourceResolver().commit();
Sling < 2.3.0 (CQ 5.5 and earlier)
Adapt your resource to PersistableValueMap, use its put and save methods:
PersistableValueMap map = resource.adaptTo(PersistableValueMap.class);
map.put("property", "value");
map.save();
JCR API
You may also adapt the resource to Node and use the JCR API to change property. However, it's a good idea to stick to one abstraction layer and in this case we somehow break the Resource abstraction provided by Sling.
Node node = resource.adaptTo(Node.class);
node.setProperty("property", "value");
node.getSession().save();
As many developers are not fond of using Node API. You can also use ValueMap and ModifiableValueMap APIs to read and update property respectively.
Read Value through ValueMap
ValueMap valueMap = resource.getValueMap();
valueMap.get("yourProperty", String.class);
Write/Modify property through ModifiableValueMap
ModifiableValueMap modifiableValueMap = resource.adaptTo(ModifiableValueMap.class);
modifiableValueMap.put("NewProperty", "Your Value"); //write
modifiableValueMap.put("OldProperty", "Updated Value"); // Modify
After writing property to a node, save these values by committing the 'resourceResolver'
You'll need system/service user for admin resourceResolver.
Go through this documentation for more info about service user.
It is not working in publish. But if user logged-In as admin it will work.
ModifiableValueMap map = resource.adaptTo(ModifiableValueMap.class);
map.put("property", "value");
resource.getResourceResolver().commit();

web api XmlMediaTypeFormatter exception

I want to use IoC / the dependency resolver of the web api framework for decoupling.
The XmlFormatter cant serialize interfaces,... Ok. But what would be the purpose of IoC and the DependencyResolver if I cant return xml?
I cant even do this:
(Method in my ApiController)
public HttpResponseMessage Get()
{
IEnumerable<Project> projects = new List<IProject>() { new Project(), new Project() }.Select(p => p as Project);
HttpResponseMessage response = Request.CreateResponse<IEnumerable<Project>>(HttpStatusCode.OK, projects);
return response;
}
I create a list of IProjects and cast them to 'Project'. But while creating the response I get this:
The configured formatter
'System.Web.Http.Tracing.Tracers.XmlMediaTypeFormatterTracer' cannot
write an object of type 'WhereSelectListIterator`2'.
That is a XmlMediaTypeFormatterTracer? I dont want tracing that throws errors while serialization. (BTW: I replaced the standard XMLformatter with my own one. However "XmlMediaTypeFormatterTracer" throws the exception...
Info: I get the same error while using the standard formatter)
Why is this XmlMediaTypeFormatterTracer called even if I implement my own xmlformatter?
my problem solved with
config.Formatters.XmlFormatter.UseXmlSerializer = false;
Have you enabled Tracing in your application? If yes, the Tracing logic wraps formatters into its a wrapper tracer formatters.

how to parse data from SOAP reponse message in java

I am using Dom4j to parse SOAP message. I had a problem:
Node node = document.selectSingleNode( "/*/soapenv:Envelope/soapenv:Body/ns:addResponse" );
when I use the above XPath, I got the following exception:
Exception: XPath expression uses unbound namespace prefix ns1
I found ways to do this: remove namespace, which is not recommended.
Any help will be appreciated. Thanks
BTW, is there a better way or toolkit for this work?
You need to create a org.dom4j.XPath object and attach suitable namespace bindings to it. Something like this:
XPath xpath = document.createXPath("/*/soapenv:Envelope/soapenv:Body/ns:addResponse");
Map<String, String> nsb = new HashMap<String, String>();
nsb.put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
nsb.put("ns", ".....");
Node node = xpath.selectSingleNode(document);
Is there a better way? Well, these days there is JAX-WS, and if there is WSDL available for your service, it is usually very simple to generate Java interfaces and classes for it.