Javax JCR Node getProperties and Titles - java

I am given a Node and I then request form it another Node.
Node nn = node.getNode("jcr:content");
From here I can do the following to get the value of
nn.getProperty("cq:lastModified")
What I am trying to do is get all the properties without asking for each one by name.
Node nn = node.getNode("jcr:content");
PropertyIterator pi = nn.getProperties();
Now I can iterate over the properties and print their values as so:
while(pi.hasNext())
{
Property p = pi.nextProperty();
String val = p.getString();
}
But how can I find the title of this Property?

I am not sure but you can try getName() method because Property interface is subinterface of Item interface. You can try like below :
while(pi.hasNext())
{
Property p = pi.nextProperty();
String name = p.getName();
String val = p.getString();
}

Related

Eclipse Milo: How to get the DataType of method argument?

Use eclipse milo to connect a OPCUA server, can use browse to get the method nodes, and then how to get the DataType of method arguments?
Just like:
final BrowseDescription browseDesc = new BrowseDescription(nodeIdRoot, BrowseDirection.Forward,
Identifiers.References, true, uint(NodeClass.Method.getValue()),
uint(BrowseResultMask.All.getValue()));
BrowseResult browseResult = client.browse(browseDesc).get();
for (final ReferenceDescription rf : browseResult.getReferences()) {
final NodeId childId = rf.getNodeId().local().orElse(null);
List<Node> nodes = client.getAddressSpace().browse(childId).get();
for (Node node : nodes) {
// Now, I get the Node of method.
// How to get the method arguments data types?
system.out.println("need Input types {}" /*, InputArgument */);
system.out.println("will get Output types {}" /*, OutputArgument */);
}
}
Method Nodes have HasProperty References to Property Nodes named InputArguments and/or OutputArguments, as long as that method receives input or output arguments.
If you read the Value Attribute if these Nodes you'll get an Argument[] describing the arguments (Name, DataType, ValueRank, ArrayDimensions, Description).
UaMethodNode has getInputArguments and getOutputArguments calls on it that can help as well:
UaMethodNode methodNode = (UaMethodNode) client.getAddressSpace().getNodeInstance(methodId).get();
CompletableFuture<Argument[]> iaf = methodNode
.getInputArguments()
.exceptionally(ex -> new Argument[0]);
CompletableFuture<Argument[]> oaf = methodNode
.getOutputArguments()
.exceptionally(ex -> new Argument[0]);
iaf.thenAcceptBoth(oaf, (ia, oa) -> {
System.out.println("inputArgs: " + Arrays.toString(ia));
System.out.println("outputArgs: " + Arrays.toString(oa));
});

Browsing OPCUA nodes only working on top level

I am using OPC UA project https://github.com/OPCFoundation/UA-Java. I was able to browse all the nodes on an OPCUA Server using UAExpert.
Now I am trying to browse all nodes using my java client. I am able to retrieve references for the nodes in the first level of the node hierarchy where
rootnameSpace = 1 and rootIdentifier = "simsre"
BrowseDescription browse = new BrowseDescription();
browse.setNodeId(new NodeId(rootnameSpace, rootIdentifier));
browse.setBrowseDirection(BrowseDirection.Forward);
browse.setIncludeSubtypes(true);
browse.setNodeClassMask(NodeClass.Object, NodeClass.Variable);
browse.setResultMask(BrowseResultMask.All );
BrowseResponse res = mySession.Browse(null, null, null, browse);
ReferenceDescription[] references = res.getResults()[0].getReferences();
When I call the code for other nodes like rootnameSpace = 31 and rootIdentifier = "/simsrede/" beneath I still get a result but no references ( so res.getResults()[0].getReferences() returns null)
- The status code of the browseResponse is something like "GOOD" -
According to specification all unicode characters are allowed in the identifiers so slashes and '|' shouldn't be the problem.
I also tried adding entries into my namespacetable and using the table to set the node id in consecutive browse requests starting at the root node with
NamespaceTable table = NamespaceTable.getDefaultInstance();
table.add(1, "urn:something:UnifiedAutomation:Uagateway");
...
//consecutive browse request starting from reference returned by first call
browse1.setNodeId(table.toNodeId(references[0].getNodeId()));
BrowseResponse res1 = mySession.Browse(null, null, null, browse);
ReferenceDescription[] references1 = res.getResults()[0].getReferences();
Anybody having an idea on why this is returning null references, or how to debug this ?
I used a Browse function
Byte[] cp;ReferenceDescriptionCollection refs; m_session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs)
and i get if refs collection of the nodes from first level. Foreach node I called Browse function in recursion where I add nodes to the collection of OPCTreeNode
public void GetChildNodes(Session sesja, ReferenceDescription Parametr, OPCTreeNode treeNode)
{
ReferenceDescriptionCollection nodes;
byte[] tmpbytes;
sesja.Browse(null, null, ExpandedNodeId.ToNodeId(Parametr.NodeId, sesja.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out tmpbytes, out nodes);
foreach (var tmpnode in nodes)
{
OPCTreeNode tmpNode = new OPCTreeNode($"{tmpnode.DisplayName}", $"{tmpnode.NodeId}");
treeNode.ChildTreeNodes.Add(tmpNode);
GetChildNodes(sesja, tmpnode, tmpNode);
}
}
OPCTreeNode class
public class OPCTreeNode // element struktury parametrów sesji
{
public string DiplayName { get; set; }
public string NodeId { get; set; }
public List<OPCTreeNode> ChildTreeNodes;
public OPCTreeNode()
{
ChildTreeNodes = new List<OPCTreeNode>();
}
public OPCTreeNode(string displayName, string nodeId)
{
this.DiplayName = displayName;
this.NodeId = nodeId;
ChildTreeNodes = new List<OPCTreeNode>();
}
}

Java NamingEnumeration - Getting a single element out of a NamingEnumeration

I am trying to fetch some users from Active Directory group and update them in another one of our site.
The task is almost done except for the part where I need to fetch the user ID from NamingEnumeration and pass it onto another method which will update it through a REST API call. Below is a part of the code where I am fetching users from AD group:
DirContext myContext = new InitialDirContext(envVars);
SearchControls searchCtrls = new SearchControls();
searchCtrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attributes = { "cn", "member"};
searchCtrls.setReturningAttributes(attributes);
String filter = "(&(objectClass=group)(cn=GROUP_NAME))";
NamingEnumeration values = myContext.search("DC=XXXX,DC=XXXX",filter,searchCtrls);
while (values.hasMoreElements())
{
SearchResult result = (SearchResult) values.next();
Attributes attribs = result.getAttributes();
if (null != attribs)
{
for (NamingEnumeration ae = attribs.getAll(); ae.hasMoreElements();)
{
Attribute atr = (Attribute) ae.next();
String attributeID = atr.getID();
for (
Enumeration vals = atr.getAll();
vals.hasMoreElements();
System.out.println(attributeID+": "+vals.nextElement())
);
}
}
}
When I run this, the output is something like below:
member: CN=USERNAME,OU=XXX,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX
member: CN=USERNAME,OU=XXX,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX
Basically, I need to fetch this CN i.e. USERNAME alone, which I will pass onto another method.
I did try to get them in a String array and process them, to no avail and I am running short of time.
Any ideas would be greatly appreciated. Thanks.
Well, I did get around this problem.
Below approach worked for me.
if (null != attribs)
{
for (NamingEnumeration ae = attribs.getAll(); ae.hasMoreElements();)
{
Attribute atr = (Attribute) ae.next();
for (
Enumeration vals = atr.getAll();
vals.hasMoreElements();
) {
list.add(vals.nextElement().toString());
}
}
}
I let the output inside a list and clipped the unwanted parts to obtain the CN alone.
Would be glad if this helps someone in the future.

Group values from a parameter list in a loop according to the prefix of the parameter

I am fetching a param list from my jsp which I need to identify according to the prefix so that I can set the values in my entity class.
The parameter names looks like the below:
List<String> reqParamNames = Arrays.asList("1_component_role", "2_component_role", "3_component_role",
"4_component_role", "1_survey_wt", "2_survey_wt", "3_survey_wt", "4_survey_wt", "1dynaGroup1", "1component_role1", "1wt1", "2dynaGroup1", "2component_role1", "2wt1", "3dynaGroup1",
"3component_role1", "3wt1", "4dynaGroup1", "4component_role1", "4wt1");
Now, from the above list, I need to get the param according to the prefix, i.e.1,2,3,4 etc. Once grouped correctly, I would need to set it to my Entity class so that I can save the parameters in my table using Hibernate.
I am unable to set the values for the dynamic table.
#RequestMapping(value = { "dynamicSettings/persist" }, method = RequestMethod.POST)
public String saveComponents(HttpServletRequest request, HttpServletResponse response,
Model model) {
LOG.debug("Entering persist area :: ");
Locale locale = LocaleUtil.getLocale();
// ToDo: validation for form
//For dynamic tables
List<String> reqParamNames = (List<String>) Collections.list((Enumeration<String>)request.getParameterNames());
for(int i =0; i < reqParamNames.size(); i++){
System.out.println("Param names are {} ::"+ reqParamNames.get(i));
String paramName = reqParamNames.get(i);
Matcher m = Pattern.compile("[^0-9]*([0-9]+).*").matcher(paramName);
if (m.matches()) {
System.out.println("Number ::" +m.group(1)); // Need to comment/remove this post development
}
System.out.println("ParamNumber ::" +""+m.group(1));
String attributeValue = request.getParameter(paramName);
System.out.println("Param Name ::"+paramName+"::: Attribute value ::"+attributeValue);
DynamicComponentSettings dynamicSettings = new DynamicComponentSettings();
if( i == paramNumber){
String group_type = request.getParameter("groupType"+i);
String component_role = request.getParameter("component_role"+i);
String survey_weight = request.getParameter("wt"+i);
System.out.println("Group Type ::"+group_type+ "::Component Role::" +component_role+ "::Survey Weight::"+survey_weight);
if(!StringUtils.isEmpty(group_type) && StringUtils.isEmpty(component_role)&&!StringUtils.isEmpty(survey_weight)){
Double survey_wt = Double.parseDouble(survey_weight);
dynamicSettings.setSurvey_wt(survey_wt);
dynamicSettings.setGroup_type(group_type);
dynamicSettings.setComponent_role(component_role);
}
}
dynamicComponentService.saveDynamicComponents(dynamicSettings);
}
**//For concrete table**
List<DynamicComponentSettings> resultList = dynamicComponentService.loadAllDynamicComponents();
for(DynamicComponentSettings component : resultList)
{
String _survey_wt = request.getParameter(component.getPk1().toString() + "survey_wt");
String _groupRoleType = request.getParameter(component.getPk1().toString() + "group_type");
String _componentRole = request.getParameter(component.getPk1().toString() + "component_role");
if(!StringUtils.isEmpty(_survey_wt) && StringUtils.isEmpty(_groupRoleType)&&!StringUtils.isEmpty(_componentRole)){
Double survey_wt = Double.parseDouble(_survey_wt);
component.setSurvey_wt(survey_wt);
component.setGroup_type(_groupRoleType);
component.setComponent_role(_componentRole);
}
dynamicComponentService.saveDynamicComponents(component);
}
return "redirect:" + "some url";
}
The concrete table works correctly, i.e. saving values correctly.
Entity class
<package declaration>
<imports>
#Entity
#Table(name = "dynamic_components")
public class DynamicComponentSettings {
/** The pk1. */
#Id
#SequenceGenerator(name = "dynamic_components_seq", sequenceName = "dynamic_components_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.AUTO, generator = "dynamic_components_seq")
private Long pk1;
private String group_type;
private String component_role;
private Double survey_wt;
<getters and setters>
}
Please provide your inputs and provide guidance as how to save the dynamic table values.
I managed to figure out the problems and fix it. There are multiple problems in that code sample. For eg. the loops are incorrect, the approach to match with the main loop was horribly wrong.
I had to get the prefix and suffix for each item, loop correctly[i.e. first get the suffix and prefix of the table and then based on suffix match, iterate through the prefix like rows] and put each dynamic table data with suffix being the key and prefix+data+suffix being the values into a Map containing linked lists. After that, I had to loop again through the Map containing the lists to set the values to my entity class correctly.
Please pardon me for not posting the code again as the method is quite long and may not be of much help. In any case, if someone does want to see how this was solved, please let me know.
Thanks for your time.

Java: Get properties of an object by parsing XML-file

I got a question regarding XML and parsing it. I use JDOM to parse my XML-File, but I got a little Problem.
A sample of my XML-File looks like this:
<IO name="Bus" type="Class">
<ResourceAttribute name="Bandwidth" type="KiloBitPerSecond" value="50" />
</IO>
Bus is a object instance of the class IO. The object got the name and type properties. Additional it has some attributes, like in the sample, the Attribute Bandwidth with the value of 50 and the datatype KiloBitPerSecond.
So when I want to loop over the file with:
for(Element packages : listPackages)
{
Map<String, Values> valueMap = new HashMap<String, Values>();
List<Element> objectInstanceList = packages.getChildren();
for(Element objects : objectInstanceList)
{
List<Element> listObjectClasses = objects.getChildren();
for(Element classes : listObjectClasses)
{
List<Element> listObjectAttributes = classes.getChildren();
for(Element objectAttributes : listObjectAttributes)
{
List<Attribute> listAttributes = objectAttributes.getAttributes();
for(Attribute attributes : listAttributes)
{
String name = attributes.getName();
String value = attributes.getValue();
AttributeType datatype = attributes.getAttributeType();
Values v = new Values(name, datatype, value);
valueMap.put(classes.getName(), v);
System.out.println(name + ":" + value);
}
}
}
}
//System.out.println(valueMap);
}
values is a class which defines the object attribute:
public class Values{
private String name;
//private AttributeType datatype;
private String value;
Thats the rest of the Code. I got two question relating that. The first one got more priority at the moment.
How do I get the values of the object(Attribute.Name = Bandwidth; Attribute.Value = 50) ? Istead that I get
name:Bus
type:Class
I thought about an additional for-loop, but the JDOM class attribute dont have a method called getAttributes().
Thats just second priority because without question 1 I cannot go further. As you see in the sample, an Attribute got 3 properties, name, type and value. How can I extract that triple put of the sample. JDOM seems just to know 2 properties for an Attribute, name and value.
thanks a lot in advance and hopefully I managed to express my self.
Edit: Added an additional for-loop in it, so the output now is:
name:Bandwidth
type:KiloBitPerSecond
value:50
That means name is the name of that property and value is the value of name. Didnt know that. At least question one is clearer now and I can try working on 2, but the new information makes 2 clearer to me.
In xml the opening tag of elements are encosoed between < and > (or />) , after the < comes the name of the element, then comes a list of attributes in the format name="value". An element can be closed inline with /> or with a closing tag </[element name]>
It would be preferable to use recursion to parse your xml instead of badly readable/maintainable nested for loops.
Here is how it could look like:
#Test
public void parseXmlRec() throws JDOMException, IOException {
String xml = "<root>"
+ "<Package>"
+ "<IO name=\"Bus\" type=\"Class\">\r\n" +
" <ResourceAttribute name=\"Bandwidth\" type=\"KiloBitPerSecond\" value=\"50\" />\r\n" +
" </IO>"
+ "</Package>"
+ "</root>";
InputStream is = new ByteArrayInputStream(xml.getBytes());
SAXBuilder sb = new SAXBuilder();
Document document = sb.build(is);
is.close();
Element root = document.getRootElement();
List<Element> children = root.getChildren();
for(Element element : children) {
parseelement(element);
}
}
private void parseelement(Element element) {
System.out.println("Element:" + element.getName());
String name = element.getAttributeValue("name");
if(name != null) {
System.out.println("name: " + name);
}
String type = element.getAttributeValue("type");
if(type != null) {
System.out.println("type: " + type);
}
String value = element.getAttributeValue("value");
if(value != null) {
System.out.println("value: " + value);
}
List<Element> children = element.getChildren();
if(children != null) {
for(Element child : children) {
parseelement(child);
}
}
}
This outputs:
Element: Package
Element: IO
name: Bus
type: Class
Element: ResourceAttribute
name: Bandwidth
type: KiloBitPerSecond
value: 50
While parsing, check the name of each element and instanciate the coresponding objects. For that I would suggest to write a separate method to handle each element. For example:
void parsePackage(Element packageElement) { ... }
parseIO(Element ioElement) { ... }
void parseResourceAttribute(Element resourceAttributeElement) { ... }

Categories

Resources