You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/08/14 17:12:50 UTC
svn commit: r1513925 - in
/sling/trunk/contrib/extensions/resource-inventory: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/sling/ src/main/java/org/apache/sling/resource/
src/main/java/org/apach...
Author: cziegeler
Date: Wed Aug 14 15:12:50 2013
New Revision: 1513925
URL: http://svn.apache.org/r1513925
Log:
SLING-3018 : Add an inventory printer which dumps a resource tree into json
Added:
sling/trunk/contrib/extensions/resource-inventory/
sling/trunk/contrib/extensions/resource-inventory/pom.xml (with props)
sling/trunk/contrib/extensions/resource-inventory/src/
sling/trunk/contrib/extensions/resource-inventory/src/main/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java (with props)
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java (with props)
sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java (with props)
Added: sling/trunk/contrib/extensions/resource-inventory/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resource-inventory/pom.xml?rev=1513925&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/resource-inventory/pom.xml (added)
+++ sling/trunk/contrib/extensions/resource-inventory/pom.xml Wed Aug 14 15:12:50 2013
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>17</version>
+ </parent>
+
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.resource.inventory</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>Apache Sling Inventory Printer Based on Resources</name>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/resourceinventory</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/resourceinventory</developerConnection>
+ <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourceinventory</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Private-Package>
+ org.apache.sling.resource.inventory.impl
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.4.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>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.inventory</artifactId>
+ <version>1.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ </dependencies>
+</project>
Propchange: sling/trunk/contrib/extensions/resource-inventory/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/resource-inventory/pom.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java?rev=1513925&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java (added)
+++ sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java Wed Aug 14 15:12:50 2013
@@ -0,0 +1,211 @@
+/*
+ * 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.resource.inventory.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+
+/**
+ * Creates a JSONObject from a resource
+ *
+ */
+public abstract class JsonObjectCreator {
+
+ /** Dump given resource in JSON, optionally recursing into its objects */
+ public static JSONObject create(final Resource resource)
+ throws JSONException {
+ final ValueMap valueMap = resource.adaptTo(ValueMap.class);
+
+ @SuppressWarnings("unchecked")
+ final Map propertyMap = (valueMap != null)
+ ? valueMap
+ : resource.adaptTo(Map.class);
+
+ final JSONObject obj = new JSONObject();
+
+ if (propertyMap == null) {
+
+ // no map available, try string
+ final String value = resource.adaptTo(String.class);
+ if (value != null) {
+
+ // single value property or just plain String resource or...
+ obj.put(resource.getName(), value);
+
+ } else {
+
+ // Try multi-value "property"
+ final String[] values = resource.adaptTo(String[].class);
+ if (values != null) {
+ obj.put(resource.getName(), new JSONArray(Arrays.asList(values)));
+ }
+
+ }
+ if ( resource.getResourceType() != null ) {
+ obj.put("sling:resourceType", resource.getResourceType());
+ }
+ if ( resource.getResourceSuperType() != null ) {
+ obj.put("sling:resourceSuperType", resource.getResourceSuperType());
+ }
+
+ } else {
+
+ @SuppressWarnings("unchecked")
+ final Iterator<Map.Entry> props = propertyMap.entrySet().iterator();
+
+ // the node's actual properties
+ while (props.hasNext()) {
+ @SuppressWarnings("unchecked")
+ final Map.Entry prop = props.next();
+
+ if ( prop.getValue() != null ) {
+ createProperty(obj, valueMap, prop.getKey().toString(),
+ prop.getValue());
+ }
+ }
+ }
+
+ // the child nodes
+ final Iterator<Resource> children = resource.listChildren();
+ while (children.hasNext()) {
+ final Resource n = children.next();
+ createSingleResource(n, obj);
+ }
+
+ return obj;
+ }
+
+ /** Used to format date values */
+ private static final String ECMA_DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z";
+
+ /** Used to format date values */
+ private static final Locale DATE_FORMAT_LOCALE = Locale.US;
+
+ private static final DateFormat CALENDAR_FORMAT = new SimpleDateFormat(ECMA_DATE_FORMAT, DATE_FORMAT_LOCALE);
+
+ private static synchronized String format(final Calendar date) {
+ return CALENDAR_FORMAT.format(date.getTime());
+ }
+
+ /** Dump only a value in the correct format */
+ private static Object getValue(final Object value) {
+ if ( value instanceof InputStream ) {
+ // input stream is already handled
+ return 0;
+ } else if ( value instanceof Calendar ) {
+ return format((Calendar)value);
+ } else if ( value instanceof Boolean ) {
+ return value;
+ } else if ( value instanceof Long ) {
+ return value;
+ } else if ( value instanceof Integer ) {
+ return value;
+ } else if ( value instanceof Double ) {
+ return value;
+ } else {
+ return value.toString();
+ }
+ }
+
+ /** Dump a single node */
+ private static void createSingleResource(final Resource n, final JSONObject parent)
+ throws JSONException {
+ parent.put(n.getName(), create(n));
+ }
+
+ /**
+ * Write a single property
+ */
+ private static void createProperty(final JSONObject obj,
+ final ValueMap valueMap,
+ final String key,
+ final Object value)
+ throws JSONException {
+ Object[] values = null;
+ if (value.getClass().isArray()) {
+ values = (Object[])value;
+ // write out empty array
+ if ( values.length == 0 ) {
+ obj.put(key, new JSONArray());
+ return;
+ }
+ }
+
+ // special handling for binaries: we dump the length and not the data!
+ if (value instanceof InputStream
+ || (values != null && values[0] instanceof InputStream)) {
+ // TODO for now we mark binary properties with an initial colon in
+ // their name
+ // (colon is not allowed as a JCR property name)
+ // in the name, and the value should be the size of the binary data
+ if (values == null) {
+ obj.put(":" + key, getLength(valueMap, -1, key, (InputStream)value));
+ } else {
+ final JSONArray result = new JSONArray();
+ for (int i = 0; i < values.length; i++) {
+ result.put(getLength(valueMap, i, key, (InputStream)values[i]));
+ }
+ obj.put(":" + key, result);
+ }
+ return;
+ }
+
+ if (!value.getClass().isArray()) {
+ obj.put(key, getValue(value));
+ } else {
+ final JSONArray result = new JSONArray();
+ for (Object v : values) {
+ result.put(getValue(v));
+ }
+ obj.put(key, result);
+ }
+ }
+
+ private static long getLength(final ValueMap valueMap,
+ final int index,
+ final String key,
+ final InputStream stream) {
+ try {
+ stream.close();
+ } catch (IOException ignore) {}
+ long length = -1;
+ if ( valueMap != null ) {
+ if ( index == -1 ) {
+ length = valueMap.get(key, length);
+ } else {
+ Long[] lengths = valueMap.get(key, Long[].class);
+ if ( lengths != null && lengths.length > index ) {
+ length = lengths[index];
+ }
+ }
+ }
+ return length;
+ }
+}
Propchange: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/JsonObjectCreator.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java?rev=1513925&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java (added)
+++ sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java Wed Aug 14 15:12:50 2013
@@ -0,0 +1,90 @@
+/*
+ * 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.resource.inventory.impl;
+
+import java.io.PrintWriter;
+import java.util.Map;
+
+import org.apache.felix.inventory.Format;
+import org.apache.felix.inventory.InventoryPrinter;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.json.JSONException;
+
+@Component(configurationFactory=true, policy=ConfigurationPolicy.REQUIRE, metatype=true)
+@Service(value=InventoryPrinter.class)
+@Properties({
+ @Property(name=InventoryPrinter.FORMAT, value="JSON", propertyPrivate=true),
+ @Property(name=InventoryPrinter.NAME),
+ @Property(name=InventoryPrinter.TITLE),
+ @Property(name=InventoryPrinter.WEBCONSOLE, boolValue=false, propertyPrivate=true)
+})
+public class ResourceInventoryPrinterFactory implements InventoryPrinter {
+
+ @Property(value = "")
+ private static final String PROP_PATH = "path";
+
+ private String path;
+
+ @Activate
+ protected void activate(final Map<String, Object> props) {
+ this.path = (String)props.get(PROP_PATH);
+ }
+
+ @Reference
+ private ResourceResolverFactory factory;
+
+ /**
+ * @see org.apache.felix.inventory.InventoryPrinter#print(java.io.PrintWriter, org.apache.felix.inventory.Format, boolean)
+ */
+ public void print(PrintWriter printWriter, Format format, boolean isZip) {
+ if ( this.path == null || !format.equals(Format.JSON) ) {
+ return;
+ }
+ ResourceResolver resolver = null;
+ try {
+ resolver = factory.getAdministrativeResourceResolver(null);
+ final Resource rootResource = resolver.getResource(this.path);
+ if ( rootResource != null ) {
+ final ResourceTraversor rt = new ResourceTraversor(rootResource);
+ rt.collectResources();
+ printWriter.write(rt.getJSONObject().toString(2));
+
+ }
+ } catch (final LoginException e) {
+ // ignore
+ } catch (JSONException e) {
+ // ignore
+ } finally {
+ if ( resolver != null ) {
+ resolver.close();
+ }
+ }
+ }
+
+}
Propchange: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceInventoryPrinterFactory.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java?rev=1513925&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java (added)
+++ sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java Wed Aug 14 15:12:50 2013
@@ -0,0 +1,120 @@
+/*
+ * 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.resource.inventory.impl;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+
+public class ResourceTraversor {
+
+ public static final class Entry {
+ public final Resource resource;
+ public final JSONObject json;
+
+ public Entry(final Resource r, final JSONObject o) {
+ this.resource = r;
+ this.json = o;
+ }
+ }
+
+ private final JSONObject startObject;
+
+ private LinkedList<Entry> currentQueue;
+
+ private LinkedList<Entry> nextQueue;
+
+ private final Resource startResource;
+
+ public ResourceTraversor(final Resource resource)
+ throws JSONException {
+ this.startResource = resource;
+ this.currentQueue = new LinkedList<Entry>();
+ this.nextQueue = new LinkedList<Entry>();
+ this.startObject = this.adapt(resource);
+ }
+
+ /**
+ * Recursive descent from startResource, collecting JSONObjects into
+ * startObject.
+ * @throws JSONException
+ */
+ public void collectResources() throws JSONException {
+ collectChildren(startResource, this.startObject, 0);
+ }
+
+ /**
+ * @param resource
+ * @param currentLevel
+ * @throws JSONException
+ */
+ private void collectChildren(final Resource resource,
+ final JSONObject jsonObj,
+ int currentLevel)
+ throws JSONException {
+
+ final Iterator<Resource> children = resource.listChildren();
+ while (children.hasNext()) {
+ final Resource res = children.next();
+ final JSONObject json = collectResource(res, jsonObj);
+ nextQueue.addLast(new Entry(res, json));
+ }
+
+ while (!currentQueue.isEmpty() || !nextQueue.isEmpty()) {
+ if (currentQueue.isEmpty()) {
+ currentLevel++;
+ currentQueue = nextQueue;
+ nextQueue = new LinkedList<Entry>();
+ }
+ final Entry nextResource = currentQueue.removeFirst();
+ collectChildren(nextResource.resource, nextResource.json, currentLevel);
+ }
+ }
+
+ /**
+ * Adds a resource in the JSON tree.
+ *
+ * @param resource The resource to add
+ * @param level The level where this resource is located.
+ * @throws JSONException
+ */
+ private JSONObject collectResource(Resource resource, final JSONObject parent)
+ throws JSONException {
+ final JSONObject o = adapt(resource);
+ parent.put(resource.getName(), o);
+ return o;
+ }
+
+ /**
+ * Adapt a Resource to a JSON Object.
+ *
+ * @param resource The resource to adapt.
+ * @return The JSON representation of the Resource
+ * @throws JSONException
+ */
+ private JSONObject adapt(final Resource resource) throws JSONException {
+ return JsonObjectCreator.create(resource);
+ }
+
+ public JSONObject getJSONObject() {
+ return startObject;
+ }
+}
Propchange: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/resource-inventory/src/main/java/org/apache/sling/resource/inventory/impl/ResourceTraversor.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url