This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.hapi-1.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-hapi.git
commit 0d016df08bbff861571f2c2f00877b078dd7560e Author: Bertrand Delacretaz <[email protected]> AuthorDate: Mon Aug 24 14:53:16 2015 +0000 SLING-4513 - import donated HApi tools git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/hapi/core@1697419 13f79535-47bb-0310-9956-ffa450edef68 --- .gitignore | 15 ++ pom.xml | 127 ++++++++++++ .../java/org/apache/sling/hapi/HApiException.java | 52 +++++ .../java/org/apache/sling/hapi/HApiProperty.java | 73 +++++++ src/main/java/org/apache/sling/hapi/HApiType.java | 93 +++++++++ src/main/java/org/apache/sling/hapi/HApiUse.java | 113 +++++++++++ src/main/java/org/apache/sling/hapi/HApiUtil.java | 103 ++++++++++ .../sling/hapi/MicrodataAttributeHelper.java | 83 ++++++++ src/main/java/org/apache/sling/hapi/TypeView.java | 104 ++++++++++ .../sling/hapi/impl/AbstractHapiTypeImpl.java | 86 +++++++++ .../apache/sling/hapi/impl/HApiPropertyImpl.java | 112 +++++++++++ .../org/apache/sling/hapi/impl/HApiTypeImpl.java | 146 ++++++++++++++ .../org/apache/sling/hapi/impl/HApiUtilImpl.java | 212 +++++++++++++++++++++ .../hapi/impl/MicrodataAttributeHelperImpl.java | 169 ++++++++++++++++ .../java/org/apache/sling/hapi/package-info.java | 23 +++ .../libs/sling/hapi/components/type/type.html | 78 ++++++++ .../resources/SLING-INF/libs/sling/hapi/types.json | 110 +++++++++++ 17 files changed, 1699 insertions(+) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..518c151 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +target/ +.project +.classpath +.settings/ +/sling/ +derby.log +*.iml +*.ipr +*.iws +coverage.em +coverage.ec +coverage/ +.DS_Store +.idea/ +bundles/extensions/models/integration-tests/sling diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..59d7fb5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +~ Licensed to the Apache Software Foundation (ASF) under one +~ or more contributor license agreements. See the NOTICE file +~ distributed with this work for additional information +~ regarding copyright ownership. The ASF licenses this file +~ to you under the Apache License, Version 2.0 (the +~ "License"); you may not use this file except in compliance +~ with the License. You may obtain a copy of the License at +~ +~ http://www.apache.org/licenses/LICENSE-2.0 +~ +~ Unless required by applicable law or agreed to in writing, +~ software distributed under the License is distributed on an +~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +~ KIND, either express or implied. See the License for the +~ specific language governing permissions and limitations +~ under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>20</version> + <relativePath/> + </parent> + + <artifactId>org.apache.sling.hapi</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>HApi - Sling Hypermedia API tools</name> + <description>Sling tools for adding support for defining, maintaining and consuming a Hypermedia API in sling components</description> + + <properties> + <sling.java.version>6</sling.java.version> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.sling</groupId> + <artifactId>maven-sling-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Category>sling</Bundle-Category> + <Sling-Initial-Content>SLING-INF;overwrite=true</Sling-Initial-Content> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.osgi</artifactId> + <version>2.1.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.api</artifactId> + <version>2.3.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.scripting.api</artifactId> + <version>2.1.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.json</artifactId> + <version>2.0.6</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <version>1.9.6</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.jcr</groupId> + <artifactId>jcr</artifactId> + <version>2.0</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.scripting.sightly</artifactId> + <version>1.0.0-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + </dependencies> + +</project> diff --git a/src/main/java/org/apache/sling/hapi/HApiException.java b/src/main/java/org/apache/sling/hapi/HApiException.java new file mode 100644 index 0000000..b9922e0 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/HApiException.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi; + +/** + * A Hypermedia API exception + */ +public class HApiException extends RuntimeException { + public HApiException() { + } + + /** + * + * @param message + */ + public HApiException(String message) { + super(message); + } + + /** + * + * @param message + * @param cause + */ + public HApiException(String message, Throwable cause) { + super(message, cause); + } + + /** + * + * @param cause + */ + public HApiException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/org/apache/sling/hapi/HApiProperty.java b/src/main/java/org/apache/sling/hapi/HApiProperty.java new file mode 100644 index 0000000..7cbe6a2 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/HApiProperty.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi; + +/** + * A Hypermedia API property for a {@link HApiType} + */ +public interface HApiProperty { + + /** + * Get the name of this property + * @return + */ + String getName(); + + /** + * Set the name of this property + * @param name + */ + void setName(String name); + + /** + * Get the description of this property + * @return + */ + String getDescription(); + + /** + * Set the description of this property + * @return + */ + void setDescription(String description); + + /** + * Get the type of this property + * @return + */ + HApiType getType(); + + /** + * Set the type of this property + * @return + */ + void setType(HApiType type); + + /** + * Whether this property is a multiple value + * @return + */ + Boolean getMultiple(); + + /** + * Set the boolean value for multiple + * @param multiple + */ + void setMultiple(Boolean multiple); +} diff --git a/src/main/java/org/apache/sling/hapi/HApiType.java b/src/main/java/org/apache/sling/hapi/HApiType.java new file mode 100644 index 0000000..e562187 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/HApiType.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ + +package org.apache.sling.hapi; + +import java.util.List; +import java.util.Map; + +/** + * A Hypermedia API type. + */ +public interface HApiType { + + /** + * The name of this type + * @return + */ + String getName(); + + + /** + * The description of this type + * @return + */ + String getDescription(); + + /** + * The JCR path of the node representing this type + * @return + */ + String getPath(); + + /** + * The URL of the node representing this type + * @return + */ + String getUrl(); + + /** + * The fully qualified domain name of this type + * @return + */ + String getFqdn(); + + /** + * A list of {@link String} representing java-like generic types that can be used as types for the properties belonging to this type + * @return + */ + List<String> getParameters(); + + /** + * A map with the names of the properties as keys and the HApiProperty object as values defined for this type + * <p>This list does not include properties inherited from the parent type</p> + * @return + */ + Map<String, HApiProperty> getProperties(); + + /** + * A map with the names of the properties as keys and the HApiProperty object as values defined for this type, + * including the properties inherited from the parent type + * @return + */ + Map<String, HApiProperty> getAllProperties(); + + /** + * Returns the parent type object + * @return + */ + HApiType getParent(); + + /** + * Whether this type is abstract or not. + * An abstract type is an identifier that does not map to a jcr node as a path or as a FQDN + * @return + */ + boolean isAbstract(); +} diff --git a/src/main/java/org/apache/sling/hapi/HApiUse.java b/src/main/java/org/apache/sling/hapi/HApiUse.java new file mode 100644 index 0000000..1dfe348 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/HApiUse.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ + +package org.apache.sling.hapi; + +import org.apache.sling.scripting.sightly.pojo.Use; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.script.Bindings; +import java.util.Map; + +/** + * Sightly use class helper to provide the hypermedia API microdata attributes for the type configured throught the 'type' binding. + * <p>The type can be a JCR path or a fully qualified domain name like in + * {@link HApiUtil#getTypeNode(org.apache.sling.api.resource.ResourceResolver, String)}</p> + * <p>The convenience get methods are meant to be used in the 'data-sly-attribute' in the sightly script.</p> + */ +public class HApiUse implements Use { + private static final Logger LOG = LoggerFactory.getLogger(HApiUse.class); + + private HApiUtil hapi; + private MicrodataAttributeHelper helper; + private SlingHttpServletRequest request; + private SlingScriptHelper sling; + private Resource resource; + private ResourceResolver resourceResolver; + private String typeId; + private Map<String, String> itemTypeAttr; + private Map<String, Map<String, String>> itemPropAttrs; + private Map<String, String> itemPropTypes; + + /** + * {@inheritDoc} + * @param bindings + */ + public void init(Bindings bindings) { + request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST); + sling = (SlingScriptHelper) bindings.get(SlingBindings.SLING); + resource = (Resource)bindings.get(SlingBindings.RESOURCE); + resourceResolver = request.getResourceResolver(); + typeId = (String) bindings.get("type"); + LOG.debug("init type: {}", typeId); + + try { + activate(); + } catch (Exception e) { + LOG.error("Failed to activate Use class", e); + } + } + + /** + * Initializes the helper and the attribute maps for the given type though the bindings + * @throws Exception + */ + public void activate() throws Exception { + hapi = sling.getService(HApiUtil.class); + helper = hapi.getHelper(resourceResolver, typeId); + itemTypeAttr = helper.itemtypeMap(); + itemPropAttrs = helper.allItemPropMap(); + itemPropTypes = helper.allPropTypesMap(); + } + + /** + * Get the itemtype html attributes map for the type + * @return + */ + public Map<String, String> getItemtype() { + LOG.debug("itemtype attrs: {}", itemTypeAttr); + return itemTypeAttr; + } + + /** + * Get the itemprop attributes map for the type, for each property. + * The key is the property name and the value is a map of html attributes for the property + * @return + */ + public Map<String, Map<String, String>> getItemprop() { + LOG.debug("itemprop attrs: {}", itemPropAttrs); + return itemPropAttrs; + } + + /** + * Get a map of the type for each property name of the type + * The key is the property name and the value is the type path in JCR + * @return + */ + public Map<String, String> getProptype() { + LOG.debug("property type attrs: {}", itemPropTypes); + return itemPropTypes; + } +} diff --git a/src/main/java/org/apache/sling/hapi/HApiUtil.java b/src/main/java/org/apache/sling/hapi/HApiUtil.java new file mode 100644 index 0000000..c262b74 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/HApiUtil.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ + +package org.apache.sling.hapi; + +import org.apache.sling.api.resource.ResourceResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +public interface HApiUtil { + public static final Logger LOG = LoggerFactory.getLogger(HApiUtil.class); + + public static final String DEFAULT_RESOURCE_TYPE = "sling/hapi/components/type"; + + /** + * <p>Get a HApi type object from a type identifier.</p> + * <p>The JCR node must be [nt:unstructured], a descendant of any of the HAPi search path defined by the + * {@see HAPI_PATHS} config and the sling:resourceType should be set to the value defined by the {@see HAPI_RESOURCE_TYPE} config</p> + * <p>The first result is returned</p> + * @param resolver The sling resource resolver object + * @param type The type identifier, which is either in the form of a jcr path, + * same as the path for {@link: ResourceResolver#getResource(String)}. If the path cannot be resolved, type is treated like + * a fully qualified domain name, which has to match the "fqdn" property on the JCR node which represents the type. + * @return The first node that matches that type or null if none is found. + * @throws RepositoryException + */ + public Node getTypeNode(ResourceResolver resolver, String type) throws RepositoryException; + + + /** + * <p>Get a HApi type object from a type identifier.</p> + * <p>The type identifier is resolved to a {@link javax.jcr.Node} and then + * {@link #fromNode(org.apache.sling.api.resource.ResourceResolver, javax.jcr.Node)} is called.</p> + * <p>For restrictions on the {@link javax.jcr.Node} + * see {@link HApiUtil#getTypeNode(org.apache.sling.api.resource.ResourceResolver, String)}</p> + * @param resolver The sling resource resolver object + * @param type The type identifier, which is either in the form of a jcr path, + * same as the path for{@link: ResourceResolver#getResource(String)}. If the path cannot be resolved, type is treated like + * a fully qualified domain name, which has to match the "fqdn" property on the JCR node which represents the type. + * @return The HApiType resolved from the type identifier + * @throws javax.jcr.RepositoryException + */ + public HApiType fromPath(ResourceResolver resolver, String type) throws RepositoryException; + + /** + * <p>Get a HApi type object from the {@link javax.jcr.Node}.</p> + * The Node has the following properties: + * <ul> + * <li>name: A 'Name' of the type (mandatory)</li> + * <li>description: A 'String' with the description text for this type (mandatory)</li> + * <li>fqdn: A 'String' with the fully qualified domain name; A namespace like a java package (mandatory)</li> + * <li>extends: A type identifier (either a path or a fqdn); (optional). This defines the parent type of this type</li> + * <li>parameter: A multivalue property to define a list of java-like generic types + * that can be used as types for properties; (optional)</li> + * </ul> + * + * <p>The properties of this type are defined as children nodes.</p> + * <p>The name of property node defines the name of the property for this type. </p> + * The children property nodes have the following properties: + * <ul> + * <li>type: The type identifier (mandatory). Can be of type 'Name' or 'Path' + * See {@link HApiUtil#getTypeNode(org.apache.sling.api.resource.ResourceResolver, String)} + * for the format of this value</li> + * <li>description: A 'String' with the description for this property (mandatory)</li> + * <li>multiple: A 'Boolean' that defines whether this property can exist multiple times on an object of this type (optional)</li> + * </ul> + * + * @param resolver The resource resolver + * @param typeNode The jcr node of the HApi type + * @return The HApiType + * @throws RepositoryException + */ + public HApiType fromNode(ResourceResolver resolver, Node typeNode) throws RepositoryException; + + /** + * Get a new instance of AttributeHelper for the type identified by 'type' + * @param resolver + * @param type See {@link #getTypeNode(org.apache.sling.api.resource.ResourceResolver, String)} + * for the format of the type identifier + * @return + * @throws RepositoryException + */ + public MicrodataAttributeHelper getHelper(ResourceResolver resolver, String type) throws RepositoryException; +} diff --git a/src/main/java/org/apache/sling/hapi/MicrodataAttributeHelper.java b/src/main/java/org/apache/sling/hapi/MicrodataAttributeHelper.java new file mode 100644 index 0000000..c52f068 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/MicrodataAttributeHelper.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi; + +import org.apache.sling.api.resource.ResourceResolver; + +import java.util.Map; + +public interface MicrodataAttributeHelper { + + /** + * Calls {@link #itemtypeMap()} and normalizes the map into a String of the form 'attr1="val1" attr2="val2"' + * @return + */ + String itemtype(); + + /** + * Get a map with the HTMl attributes for a new item of the type defined through + * a new {@link MicrodataAttributeHelper} object + * <p>The key is the HTMl attribute name and the value is the HTML attribute value</p> + * @return + */ + Map<String, String> itemtypeMap(); + + /** + * Calls {@link #itemprop(String, boolean)} with 'withType' true + * @param propName + * @return + */ + String itemprop(String propName); + + /** + * Calls {@link #itempropMap(String, boolean)} and normalizes the map into a String of the form 'attr1="val1" attr2="val2"' + * @param propName + * @param withType + * @return + */ + String itemprop(String propName, boolean withType); + + /** + * Get a map with the HTMl attributes for the given property of the type defined through + * a new {@link MicrodataAttributeHelper} + * <p>The key is the HTMl attribute name and the value is the HTML attribute value</p> + * <p> Will through a {@link HApiException} + * runtime exception if the property propName does not exist for the type</p> + * @param propName the name of the property + * @param withType whether to include the 'itemtype' attribute + * @return + */ + Map<String, String> itempropMap(String propName, boolean withType); + + /** + * Get a map of maps with the HTMl attributes for each property of the type defined through + * a new {@link MicrodataAttributeHelper} + * <p>The key is the property name and the value is a map of attributes like the one returned + * by {@link #itempropMap(String, boolean)}</p> + * @return + */ + Map<String, Map<String, String>> allItemPropMap(); + + /** + * Get a map of types for each type property. + * <p> The key is the property name and the value is the type path identifier of that property</p> + * @return + */ + Map<String, String> allPropTypesMap(); +} diff --git a/src/main/java/org/apache/sling/hapi/TypeView.java b/src/main/java/org/apache/sling/hapi/TypeView.java new file mode 100644 index 0000000..3fb0d33 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/TypeView.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.scripting.sightly.pojo.Use; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.script.Bindings; +import java.util.*; + +public class TypeView implements Use { + private static final Logger LOG = LoggerFactory.getLogger(TypeView.class); + + private HApiUtil hapi; + private HApiType me; + private HApiType parent; + + private String description; + private SlingHttpServletRequest request; + private SlingScriptHelper sling; + private Resource resource; + private ResourceResolver resourceResolver; + + public void init(Bindings bindings) { + request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST); + sling = (SlingScriptHelper) bindings.get(SlingBindings.SLING); + resource = (Resource)bindings.get(SlingBindings.RESOURCE); + resourceResolver = request.getResourceResolver(); + + try { + activate(); + } catch (Exception e) { + LOG.error("Failed to activate Use class", e); + } + } + + public void activate() throws Exception { + hapi = sling.getService(HApiUtil.class); + me = hapi.fromPath(resourceResolver, resource.getPath()); + LOG.debug("me: {} resource: {}", me, resource.getPath()); + description = me.getDescription(); + parent = me.getParent(); + } + + public String getTitle() { + return me.getFqdn(); + } + + public String getDescription() { + return description; + } + + public String getParentUrl() { + if (null != parent) { + return parent.getUrl(); + } else { + return null; + } + } + + public String getParentFqdn() { + if (null != parent) { + return parent.getFqdn(); + } else { + return null; + } + } + + public List<String> getParameters() { + return me.getParameters(); + } + + public List<HApiProperty> getProps() { + List<HApiProperty> props = new ArrayList<HApiProperty>(me.getAllProperties().values()); + LOG.debug("props: ", props); + return props; + } + + public boolean getHasProps() { + return getProps().size() > 0; + } +} diff --git a/src/main/java/org/apache/sling/hapi/impl/AbstractHapiTypeImpl.java b/src/main/java/org/apache/sling/hapi/impl/AbstractHapiTypeImpl.java new file mode 100644 index 0000000..6469522 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/impl/AbstractHapiTypeImpl.java @@ -0,0 +1,86 @@ +/************************************************************************* + * + * ADOBE CONFIDENTIAL + * __________________ + * + * Copyright 2014 Adobe Systems Incorporated + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains + * the property of Adobe Systems Incorporated and its suppliers, + * if any. The intellectual and technical concepts contained + * herein are proprietary to Adobe Systems Incorporated and its + * suppliers and may be covered by U.S. and Foreign Patents, + * patents in process, and are protected by trade secret or copyright law. + * Dissemination of this information or reproduction of this material + * is strictly forbidden unless prior written permission is obtained + * from Adobe Systems Incorporated. + **************************************************************************/ +package org.apache.sling.hapi.impl; + +import org.apache.sling.hapi.HApiProperty; +import org.apache.sling.hapi.HApiType; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AbstractHapiTypeImpl implements HApiType { + + public static final String ABSTRACT = "Abstract"; + private final String name; + + public AbstractHapiTypeImpl(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return ABSTRACT; + } + + @Override + public String getPath() { + return null; + } + + @Override + public String getUrl() { + return null; + } + + @Override + public String getFqdn() { + return null; + } + + @Override + public List<String> getParameters() { + return null; + } + + @Override + public Map<String, HApiProperty> getProperties() { + return new HashMap<String, HApiProperty>(); + } + + @Override + public Map<String, HApiProperty> getAllProperties() { + return getProperties(); + } + + @Override + public HApiType getParent() { + return null; + } + + @Override + public boolean isAbstract() { + return true; + } +} diff --git a/src/main/java/org/apache/sling/hapi/impl/HApiPropertyImpl.java b/src/main/java/org/apache/sling/hapi/impl/HApiPropertyImpl.java new file mode 100644 index 0000000..cb3a280 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/impl/HApiPropertyImpl.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi.impl; + +import org.apache.sling.hapi.HApiType; +import org.apache.sling.hapi.HApiProperty; + +/** + * {@inheritDoc} + */ +public class HApiPropertyImpl implements HApiProperty { + private String name; + private String description; + private HApiType type; + private Boolean multiple; + + /** + * + * @param name + * @param description + * @param type + * @param multiple + */ + public HApiPropertyImpl(String name, String description, HApiType type, Boolean multiple) { + this.name = name; + this.description = description; + this.type = type; + this.multiple = multiple; + } + + /** + * {@inheritDoc} + */ + public String getName() { + return name; + } + + /** + * {@inheritDoc} + */ + public void setName(String name) { + this.name = name; + } + + /** + * {@inheritDoc} + */ + public String getDescription() { + return description; + } + + /** + * {@inheritDoc} + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * {@inheritDoc} + */ + public HApiType getType() { + return type; + } + + /** + * {@inheritDoc} + */ + public void setType(HApiType type) { + this.type = type; + } + + /** + * {@inheritDoc} + */ + public Boolean getMultiple() { + return multiple; + } + + /** + * {@inheritDoc} + */ + public void setMultiple(Boolean multiple) { + this.multiple = multiple; + } + + @Override + public String toString() { + return "HApiProperty{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", type=" + type + + ", multiple=" + multiple + + '}'; + } +} diff --git a/src/main/java/org/apache/sling/hapi/impl/HApiTypeImpl.java b/src/main/java/org/apache/sling/hapi/impl/HApiTypeImpl.java new file mode 100644 index 0000000..faa6e1e --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/impl/HApiTypeImpl.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi.impl; + +import org.apache.sling.hapi.HApiProperty; +import org.apache.sling.hapi.HApiType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.*; + +/** + * {@inheritDoc} + */ +public class HApiTypeImpl implements HApiType { + + public static final Logger LOG = LoggerFactory.getLogger(HApiTypeImpl.class); + + private final HApiType parent; + + private String name; + + private String description; + private String path; + private String fqdn; + private List<String> parameters; + private Map<String, HApiProperty> properties; + private boolean isAbstract; + + /** + * A new HApiType + * @param name + * @param description + * @param path + * @param fqdn + * @param parameters + * @param properties + * @param parent + */ + public HApiTypeImpl(String name, String description, String path, String fqdn, List<String> parameters, Map<String, + HApiProperty> properties, HApiType parent, boolean isAbstract) { + this.name = name; + this.description = description; + this.path = path; + this.fqdn = fqdn; + this.parameters = parameters; + this.properties = properties; + this.parent = parent; + this.isAbstract = isAbstract; + } + + + /** + * {@inheritDoc} + */ + public String getName() { + return name; + } + + /** + * {@inheritDoc} + */ + public String getDescription() { + return description; + } + + /** + * {@inheritDoc} + */ + public String getPath() { + return path; + } + + /** + * {@inheritDoc} + */ + public String getUrl() { + return getPath() + ".html"; + } + + /** + * {@inheritDoc} + */ + public String getFqdn() { + return fqdn; + } + + /** + * {@inheritDoc} + */ + public List<String> getParameters() { + return parameters; + } + + /** + * {@inheritDoc} + */ + public Map<String, HApiProperty> getProperties() { + return properties; + } + + /** + * {@inheritDoc} + */ + public Map<String, HApiProperty> getAllProperties() { + Map<String, HApiProperty> allProps = new HashMap<String, HApiProperty>(); + LOG.debug("parent: {}", parent); + if (null != parent) { + Map<String, HApiProperty> parentProps = parent.getAllProperties(); + LOG.debug("parent props: {}", parentProps); + allProps.putAll(parentProps); + } + allProps.putAll(getProperties()); + return allProps; + } + + /** + * {@inheritDoc} + */ + public HApiType getParent() { + return parent; + } + + /** + * {@inheritDoc} + */ + public boolean isAbstract() { + return isAbstract; + } + +} diff --git a/src/main/java/org/apache/sling/hapi/impl/HApiUtilImpl.java b/src/main/java/org/apache/sling/hapi/impl/HApiUtilImpl.java new file mode 100644 index 0000000..a8f3d51 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/impl/HApiUtilImpl.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi.impl; + +import org.apache.sling.hapi.HApiProperty; +import org.apache.sling.hapi.HApiType; +import org.apache.sling.hapi.MicrodataAttributeHelper; +import org.apache.sling.hapi.HApiUtil; +import org.apache.felix.scr.annotations.*; +import org.apache.felix.scr.annotations.Property; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.*; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; +import java.util.*; + + +@Component(label = "Apache Sling Hypermedia API tools", metatype = true) +@Service() + +public class HApiUtilImpl implements HApiUtil { + + @Property(label = "HApi Resource Type", cardinality = 0, value = DEFAULT_RESOURCE_TYPE) + public static final String HAPI_RESOURCE_TYPE = "org.apache.sling.hapi.tools.resourcetype"; + + + @Property(label = "HApi Types Search Paths", cardinality=50, value = {"/libs/sling/hapi/types"}) + public static final String HAPI_PATHS = "org.apache.sling.hapi.tools.searchpaths"; + + public static String resourceType; + public static String[] hApiPaths; + + + @Activate + private void activate(ComponentContext context, Map<String, Object> configuration) { + resourceType = PropertiesUtil.toString(configuration.get(HAPI_RESOURCE_TYPE), DEFAULT_RESOURCE_TYPE); + hApiPaths = PropertiesUtil.toStringArray(configuration.get(HAPI_PATHS)); + } + + /** + * {@inheritDoc} + */ + public Node getTypeNode(ResourceResolver resolver, String type) throws RepositoryException { + Session session = resolver.adaptTo(Session.class); + + // Try to resolve the resource as a path + Resource res = resolver.getResource(type); + if (null != res) { + LOG.debug("res = " + res.getName() + " " + res.getPath()); + return res.adaptTo(Node.class); + } else { + for (String path : new HashSet<String>(Arrays.asList(hApiPaths))) { + // Remove trailing slash from path + path = (path.endsWith("/")) ? path.substring(0,path.length() - 1) : path; + + // Get the query manager for the session + QueryManager queryManager = session.getWorkspace().getQueryManager(); + + // Build query for the search paths + StringBuilder queryString = new StringBuilder("SELECT * FROM [nt:unstructured] WHERE "); + queryString.append(String.format("ISDESCENDANTNODE([%s]) ", path)); + queryString.append(String.format("AND [sling:resourceType]='%s' AND fqdn = '%s'", resourceType, type)); + + // Execute query + Query query = queryManager.createQuery(queryString.toString(), Query.JCR_SQL2); + LOG.debug("Querying HAPi: {}", queryString.toString()); + QueryResult result = query.execute(); + + NodeIterator nodeIter = result.getNodes(); + if (nodeIter.hasNext()) { + return nodeIter.nextNode(); + } else { + // continue + } + } + + // Type has to be abstract + return null; + } + } + + + /** + * {@inheritDoc} + */ + public HApiType fromPath(ResourceResolver resolver, String type) throws RepositoryException { + Node typeNode = this.getTypeNode(resolver, type); + LOG.debug("typeNode=" + typeNode); + if (null == typeNode) { + return new AbstractHapiTypeImpl(type); + } else { + return fromNode(resolver, typeNode); + } + } + + /** + * {@inheritDoc} + */ + public HApiType fromNode(ResourceResolver resolver, Node typeNode) throws RepositoryException { + if (null == typeNode) return null; + String name = typeNode.getProperty("name").getValue().getString(); + String description = typeNode.getProperty("description").getValue().getString(); + String path = typeNode.getPath(); + String fqdn = typeNode.getProperty("fqdn").getValue().getString(); + + // get parent if it exists + HApiType parent = null; + String parentPath = typeNode.hasProperty("extends") ? typeNode.getProperty("extends").getString() : null; + if (null != parentPath) { + parent = this.fromPath(resolver, parentPath); + } + + // get parameters + Value[] parameterValues = typeNode.hasProperty("parameters") ? typeNode.getProperty("parameters").getValues() : new Value[]{}; + List<String> parameters = new ArrayList<String>(parameterValues.length); + + for (Value p : Arrays.asList(parameterValues)) { + parameters.add(p.getString()); + } + + // Get properties + Map<String, HApiProperty> properties = new HashMap<String, HApiProperty>(); + + // Add the properties from this node + Iterator<Node> it = typeNode.getNodes(); + while (it.hasNext()) { + Node propNode = it.next(); + String propName = propNode.getName(); + String propDescription = propNode.hasProperty("description") ? propNode.getProperty("description").getString() : ""; + + // TODO: maybe create adapter and use adaptTo() + // TODO: this could be slow, the types can be instantiated externally in a service activate() + String type = propNode.getProperty("type").getValue().getString(); + HApiType propType = this.fromPath(resolver, type); + Boolean propMultiple = propNode.hasProperty("multiple") ? propNode.getProperty("multiple").getBoolean() : false; + + HApiProperty prop = new HApiPropertyImpl(propName, propDescription, propType, propMultiple); + properties.put(prop.getName(), prop); + } + return new HApiTypeImpl(name, description, path, fqdn, parameters, properties, parent, false); + } + + /** + * {@inheritDoc} + */ + public MicrodataAttributeHelper getHelper(ResourceResolver resolver, String type) throws RepositoryException { + return new MicrodataAttributeHelperImpl(resolver, TypesCache.getInstance(this).getType(resolver, type)); + } +} + +/** + * <p>Cache for types</p> + * + */ +class TypesCache { + private static final Logger LOG = LoggerFactory.getLogger(TypesCache.class); + Map<String, HApiType> types; + private static TypesCache singleton = null; + private HApiUtil hApiUtil; + + public static TypesCache getInstance(HApiUtil hApiUtil) { + if (null == singleton) { + singleton = new TypesCache(hApiUtil); + } + LOG.debug("singleton: {}", singleton); + return singleton; + } + + private TypesCache(HApiUtil hApiUtil) { + this.types = new HashMap<String, HApiType>(); + this.hApiUtil = hApiUtil; + } + + public HApiType getType(ResourceResolver resolver, String typePath) throws RepositoryException { + if (types.containsKey(typePath)) { + return this.types.get(typePath); + } else { + + HApiType type = hApiUtil.fromPath(resolver, typePath); + types.put(type.getPath(), type); + return type; + } + } + + public void addType(HApiType type) { + this.types.put(type.getPath(), type); + } +} + diff --git a/src/main/java/org/apache/sling/hapi/impl/MicrodataAttributeHelperImpl.java b/src/main/java/org/apache/sling/hapi/impl/MicrodataAttributeHelperImpl.java new file mode 100644 index 0000000..8b06163 --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/impl/MicrodataAttributeHelperImpl.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.sling.hapi.impl; + +import org.apache.sling.hapi.HApiProperty; +import org.apache.sling.hapi.HApiType; +import org.apache.sling.hapi.MicrodataAttributeHelper; +import org.apache.sling.hapi.HApiException; +import org.apache.sling.api.resource.ResourceResolver; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Helper class for HTML microdata attributes + */ +public class MicrodataAttributeHelperImpl implements MicrodataAttributeHelper { + private final ResourceResolver resolver; + HApiType type; + + /** + * Get a new microdata html attributes helper for the given HApiType object. + * <p>Provides convenience methods to get the html attributes needed for instrumenting the markup with a Hypermedia API</p> + * @param resolver + * @param type + */ + public MicrodataAttributeHelperImpl(ResourceResolver resolver, HApiType type) { + this.resolver = resolver; + this.type = type; + } + + /** + * {@inheritDoc} + */ + public String itemtype() { + return itemtypeMap().toString(); + } + + /** + * {@inheritDoc} + */ + public Map<String, String> itemtypeMap() { + Map<String, String> attrMap = new AttrMap(2); + attrMap.put("itemtype", type.getPath() + ".html"); + attrMap.put("itemscope", !type.getAllProperties().isEmpty()); + + return attrMap; + } + + /** + * {@inheritDoc} + */ + public String itemprop(String propName) { + return itemprop(propName, true); + } + + /** + * {@inheritDoc} + */ + public String itemprop(String propName, boolean withType) { + return itempropMap(propName, withType).toString(); + } + + /** + * {@inheritDoc} + */ + public Map<String, String> itempropMap(String propName, boolean withType) { + HApiProperty prop = this.type.getAllProperties().get(propName); + if (null == prop) throw new HApiException("Property " + propName + " does not exist for type " + type.getPath()); + + Map<String, String> attrMap = new AttrMap(3); + attrMap.put("itemprop", propName); + if (withType) { + attrMap.putAll(new MicrodataAttributeHelperImpl(resolver, prop.getType()).itemtypeMap()); + } + return attrMap; + } + + /** + * {@inheritDoc} + */ + public Map<String, Map<String, String>> allItemPropMap() { + Map<String, Map<String, String>> m = new PropMap(type); + for (String prop: type.getAllProperties().keySet()) { + m.put(prop, itempropMap(prop, true)); + } + return m; + } + + /** + * {@inheritDoc} + */ + public Map<String, String> allPropTypesMap() { + Map<String, HApiProperty> props = type.getAllProperties(); + Map<String, String> types = new HashMap<String, String>(props.size()); + for (String propName : props.keySet()) { + types.put(propName, props.get(propName).getType().getPath()); + } + return types; + } + + + /** + * {@inheritDoc} + */ + private class PropMap extends HashMap<String, Map<String, String>> { + + private final HApiType type; + + public PropMap(HApiType type) { + super(); + this.type = type; + } + + @Override + public Map<String, String> get(Object key) { + Map<String, String> val = super.get(key); + if (null == val) { + throw new HApiException("Property " + key + " does not exist for type " + type.getPath()); + } + return val; + } + } + + /** + * {@inheritDoc} + */ + private class AttrMap extends HashMap<String, String> { + + public AttrMap(int i) { + super(i); + } + + public AttrMap() { + super(); + } + + public AttrMap(int initialCapacity, float loadFactor) { + super(initialCapacity, loadFactor); + } + + @Override + public String toString() { + String norm = ""; + for (Map.Entry<String, String> entry : this.entrySet()) { + norm += entry.getKey() + "=\"" + entry.getValue() + "\"" + " "; + } + return norm; + } + } +} + diff --git a/src/main/java/org/apache/sling/hapi/package-info.java b/src/main/java/org/apache/sling/hapi/package-info.java new file mode 100644 index 0000000..fcded2d --- /dev/null +++ b/src/main/java/org/apache/sling/hapi/package-info.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ + +@Version("1.0.0") +package org.apache.sling.hapi; + +import aQute.bnd.annotation.Version; diff --git a/src/main/resources/SLING-INF/libs/sling/hapi/components/type/type.html b/src/main/resources/SLING-INF/libs/sling/hapi/components/type/type.html new file mode 100644 index 0000000..b24977c --- /dev/null +++ b/src/main/resources/SLING-INF/libs/sling/hapi/components/type/type.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> +<html data-sly-use.type="org.apache.sling.hapi.TypeView" lang="${type.lang}"> + + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <!-- Bootstrap --> + <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"> + + <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> + <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> + <!--[if lt IE 9]> + <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> + <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> + <![endif]--> + + <title>${type.title}</title> + + </head> + <body> + <div class="container"> + + <h1>${type.title}</h1> + <div> + <p>${type.description}</p> + </div> + <h2 data-sly-test.parentUrl="${type.parentUrl}"> extends + <a href="${parentUrl}" >${type.parentFqdn}</a> + </h2> + <h3 data-sly-test="${type.parameters}">Parameters: </h3> + <ul data-sly-list.param="${type.parameters}" title="Parameters" class="list-inline"> + <li>${param}</li> + </ul> + <h3>Properties: </h3> + <table class="table" data-sly-test.props="${type.props}"> + <thead> + <tr> + <th>Property</th> + <th>Expected Type</th> + <th>Multiple</th> + <th>Description</th> + </tr> + </thead> + <tbody data-sly-list.prop="${type.props}"> + <tr> + <th>${prop.name}</th> + <td> + <a href="${prop.type.url}">${prop.type.name}</a> + </td> + <td>${prop.multiple}</td> + <td>${prop.description}</td> + </tr> + </tbody> + </table> + <div data-sly-test="${!props}">None</div> + </div> + </body> +</html> diff --git a/src/main/resources/SLING-INF/libs/sling/hapi/types.json b/src/main/resources/SLING-INF/libs/sling/hapi/types.json new file mode 100644 index 0000000..7984006 --- /dev/null +++ b/src/main/resources/SLING-INF/libs/sling/hapi/types.json @@ -0,0 +1,110 @@ +{ + "jcr:primaryType": "sling:Folder", + "image": { + "jcr:primaryType": "nt:unstructured", + "description": "An image src", + "fqdn": "org.apache.sling.hapi.common.Image", + "name": "Image", + "sling:resourceType": "sling/hapi/components/type" + }, + "date": { + "jcr:primaryType": "nt:unstructured", + "description": "a date value; format has to be described in each property of this type", + "fqdn": "org.apache.sling.hapi.common.Date", + "name": "Date", + "sling:resourceType": "sling/hapi/components/type" + }, + "text": { + "jcr:primaryType": "nt:unstructured", + "description": "A text value", + "fqdn": "org.apache.sling.hapi.common.Text", + "name": "Text", + "sling:resourceType": "sling/hapi/components/type" + }, + "collection": { + "jcr:primaryType": "nt:unstructured", + "description": "Generic collection type. Can be parameterized with a generic type.", + "fqdn": "org.apache.sling.hapi.common.collection", + "name": "collection", + "parameters": [ + "T" + ], + "sling:resourceType": "sling/hapi/components/type", + "item": { + "jcr:primaryType": "nt:unstructured", + "description": "", + "type": "T", + "multiple": true + } + }, + "boolean": { + "jcr:primaryType": "nt:unstructured", + "description": "true or false", + "fqdn": "org.apache.sling.hapi.common.Boolean", + "name": "Boolean", + "sling:resourceType": "sling/hapi/components/type" + }, + "pair": { + "jcr:primaryType": "nt:unstructured", + "description": "The key-value pair. Usually used to indicate a Map entry.", + "fqdn": "org.apache.sling.hapi.common.pair", + "name": "pair", + "parameters": [ + "K", + "V" + ], + "sling:resourceType": "sling/hapi/components/type", + "key": { + "jcr:primaryType": "nt:unstructured", + "description": "The key of the pair", + "type": "K", + "multiple": false + }, + "value": { + "jcr:primaryType": "nt:unstructured", + "description": "The value of the pair", + "type": "V", + "multiple": false + } + }, + "number": { + "jcr:primaryType": "nt:unstructured", + "description": "A number value", + "fqdn": "org.apache.sling.hapi.common.Number", + "name": "Number", + "sling:resourceType": "sling/hapi/components/type" + }, + "demo_type": { + "jcr:primaryType": "nt:unstructured", + "description": "A demo HApi type to show a more advanced structure", + "demo_description": { + "jcr:primaryType": "nt:unstructured", + "description": "The description of the demo object", + "type": "org.apache.sling.hapi.common.Text", + "multiple": false + }, + "fqdn": "org.apache.sling.hapi.common.collection", + "name": "collection", + "parameters": [], + "sling:resourceType": "sling/hapi/components/type", + "title": { + "jcr:primaryType": "nt:unstructured", + "description": "The title of the demo object", + "type": "org.apache.sling.hapi.common.Text", + "multiple": false + }, + "entries": { + "jcr:primaryType": "nt:unstructured", + "description": "An entry of type pair in the demo object", + "type": "org.apache.sling.hapi.common.pair", + "multiple": true + } + }, + "url": { + "jcr:primaryType": "nt:unstructured", + "description": "A URL value type", + "fqdn": "org.apache.sling.hapi.common.URL", + "name": "URL", + "sling:resourceType": "sling/hapi/components/type" + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
