Support for standard ACR properties
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 24 Sep 2023 09:34:29 +0000 (11:34 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 24 Sep 2023 09:34:29 +0000 (11:34 +0200)
org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/BasicSearchToQom.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrContent.java
org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrName.java [new file with mode: 0644]

index 72940705a0f07aa2f1ce0bcb828cfa025375a50d..5ed36b8a29878339944bf55c3d12b069e2494637 100644 (file)
@@ -1,8 +1,11 @@
 package org.argeo.cms.jcr.acr;
 
+import static javax.jcr.query.qom.QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO;
+
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.query.QueryManager;
@@ -15,12 +18,14 @@ import javax.jcr.query.qom.StaticOperand;
 import javax.xml.namespace.QName;
 
 import org.apache.jackrabbit.commons.query.sql2.QOMFormatter;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.NamespaceUtils;
 import org.argeo.api.acr.search.BasicSearch;
 import org.argeo.api.acr.search.Constraint;
 import org.argeo.api.acr.search.ContentFilter;
 import org.argeo.api.acr.search.ContentFilter.Eq;
 import org.argeo.api.acr.search.ContentFilter.IsContentClass;
+import org.argeo.api.acr.search.ContentFilter.IsDefined;
 import org.argeo.api.acr.search.ContentFilter.Not;
 import org.argeo.api.cms.CmsLog;
 
@@ -114,14 +119,29 @@ class BasicSearchToQom {
                        }
 
                } else if (constraint instanceof Eq comp) {
-                       DynamicOperand dynamicOperand = factory.propertyValue(selectorName,
-                                       NamespaceUtils.toPrefixedName(comp.getProp()));
+                       QName prop = comp.getProp();
+                       if (DName.creationdate.equals(prop))
+                               prop = JcrName.created.qName();
+                       else if (DName.getlastmodified.equals(prop))
+                               prop = JcrName.lastModified.qName();
+
+                       DynamicOperand dynamicOperand = factory.propertyValue(selectorName, NamespaceUtils.toPrefixedName(prop));
                        // TODO better convert attribute value
                        StaticOperand staticOperand = factory
                                        .literal(session.getValueFactory().createValue(comp.getValue().toString()));
-                       return factory.comparison(dynamicOperand, QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO, staticOperand);
+                       return factory.comparison(dynamicOperand, JCR_OPERATOR_EQUAL_TO, staticOperand);
                } else if (constraint instanceof Not not) {
                        return factory.not(toQomConstraint(not.getNegated()));
+               } else if (constraint instanceof IsDefined comp) {
+                       QName prop = comp.getProp();
+                       if (DName.checkedIn.equals(prop) || DName.checkedOut.equals(prop)) {
+                               DynamicOperand dynamicOperand = factory.propertyValue(selectorName, Property.JCR_IS_CHECKED_OUT);
+                               StaticOperand staticOperand = factory
+                                               .literal(session.getValueFactory().createValue(DName.checkedOut.equals(prop)));
+                               return factory.comparison(dynamicOperand, JCR_OPERATOR_EQUAL_TO, staticOperand);
+                       } else {
+                               return factory.propertyExistence(selectorName, NamespaceUtils.toPrefixedName(prop));
+                       }
                } else {
                        throw new IllegalArgumentException("Constraint " + constraint.getClass() + " is not supported");
                }
index a46dd859fd0e5df2f605da056eba5d9d96be80c8..149ef3acf524fc6c8a1c31458fc9db893c5a913d 100644 (file)
@@ -36,6 +36,7 @@ import javax.xml.transform.stream.StreamSource;
 
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.CrAttributeType;
+import org.argeo.api.acr.DName;
 import org.argeo.api.acr.NamespaceUtils;
 import org.argeo.api.acr.spi.ProvidedSession;
 import org.argeo.api.cms.CmsConstants;
@@ -92,7 +93,38 @@ public class JcrContent extends AbstractContent {
        @SuppressWarnings("unchecked")
        @Override
        public <A> Optional<A> get(QName key, Class<A> clss) {
-               Object value = get(getJcrNode(), key.toString());
+               Node node = getJcrNode();
+               if (DName.creationdate.equals(key))
+                       key = JcrName.created.qName();
+               else if (DName.getlastmodified.equals(key))
+                       key = JcrName.lastModified.qName();
+               else if (DName.checkedOut.equals(key)) {
+                       try {
+                               if (!node.hasProperty(Property.JCR_IS_CHECKED_OUT))
+                                       return Optional.empty();
+                               boolean isCheckedOut = node.getProperty(Property.JCR_IS_CHECKED_OUT).getBoolean();
+                               if (!isCheckedOut)
+                                       return Optional.empty();
+                               // FIXME return URI
+                               return (Optional<A>) Optional.of(new Object());
+                       } catch (RepositoryException e) {
+                               throw new JcrException(e);
+                       }
+               } else if (DName.checkedIn.equals(key)) {
+                       try {
+                               if (!node.hasProperty(Property.JCR_IS_CHECKED_OUT))
+                                       return Optional.empty();
+                               boolean isCheckedOut = node.getProperty(Property.JCR_IS_CHECKED_OUT).getBoolean();
+                               if (isCheckedOut)
+                                       return Optional.empty();
+                               // FIXME return URI
+                               return (Optional<A>) Optional.of(new Object());
+                       } catch (RepositoryException e) {
+                               throw new JcrException(e);
+                       }
+               }
+
+               Object value = get(node, key.toString());
                if (value instanceof List<?> lst)
                        return Optional.of((A) lst);
                // TODO check other collections?
@@ -111,12 +143,23 @@ public class JcrContent extends AbstractContent {
        @Override
        protected Iterable<QName> keys() {
                try {
+                       Node node = getJcrNode();
                        Set<QName> keys = new HashSet<>();
-                       for (PropertyIterator propertyIterator = getJcrNode().getProperties(); propertyIterator.hasNext();) {
+                       for (PropertyIterator propertyIterator = node.getProperties(); propertyIterator.hasNext();) {
                                Property property = propertyIterator.nextProperty();
+                               QName name = NamespaceUtils.parsePrefixedName(provider, property.getName());
+
                                // TODO convert standard names
+                               if (property.getName().equals(Property.JCR_CREATED))
+                                       name = DName.creationdate.qName();
+                               if (property.getName().equals(Property.JCR_LAST_MODIFIED))
+                                       name = DName.getlastmodified.qName();
+                               if (property.getName().equals(Property.JCR_IS_CHECKED_OUT)) {
+                                       boolean isCheckedOut = node.getProperty(Property.JCR_IS_CHECKED_OUT).getBoolean();
+                                       name = isCheckedOut ? DName.checkedOut.qName() : DName.checkedIn.qName();
+                               }
+
                                // TODO skip technical properties
-                               QName name = NamespaceUtils.parsePrefixedName(provider, property.getName());
                                keys.add(name);
                        }
                        return keys;
@@ -202,12 +245,10 @@ public class JcrContent extends AbstractContent {
        public int getSiblingIndex() {
                return Jcr.getIndex(getJcrNode());
        }
-       
-       
 
        @Override
        public String getText() {
-               return  JcrxApi.getXmlValue(getJcrNode());
+               return JcrxApi.getXmlValue(getJcrNode());
        }
 
        /*
diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrName.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/acr/JcrName.java
new file mode 100644 (file)
index 0000000..de0d1b1
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.cms.jcr.acr;
+
+import org.argeo.api.acr.QNamed;
+
+public enum JcrName implements QNamed {
+       created, lastModified, isCheckedOut;
+
+       @Override
+       public String getNamespace() {
+               return JcrContentNamespace.JCR.getNamespaceURI();
+       }
+
+       @Override
+       public String getDefaultPrefix() {
+               return JcrContentNamespace.JCR.getDefaultPrefix();
+       }
+
+}