/* * Copyright 2015 Time Warner Cable, Inc. * * Licensed 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 com.twcable.jackalope.impl.sling; import com.day.cq.dam.api.Asset; import com.day.cq.wcm.api.Page; import com.twcable.jackalope.JcrConstants; import com.twcable.jackalope.impl.common.Paths; import com.twcable.jackalope.impl.cq.AssetImpl; import com.twcable.jackalope.impl.cq.PageImpl; import com.twcable.jackalope.impl.jcr.JcrUtils; import org.apache.sling.api.resource.ModifiableValueMap; import org.apache.sling.api.resource.PersistableValueMap; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceUtil; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.jcr.resource.JcrModifiablePropertyMap; import org.apache.sling.jcr.resource.JcrPropertyMap; import org.apache.sling.jcr.resource.internal.JcrModifiableValueMap; import javax.jcr.Node; import javax.jcr.Property; import javax.jcr.RepositoryException; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT; import static org.apache.jackrabbit.JcrConstants.JCR_DATA; import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; import static org.apache.jackrabbit.JcrConstants.NT_FILE; /** * Implement sling Resource for a jcr Node */ public class NodeResourceImpl extends ItemResourceImpl { private final Node node; /** * Construct a new NodeResourceImpl. * * @param resourceResolver ResourceResolver that constructed this NodeResourceImpl * @param node The constructed ResourceNodeImpl */ public NodeResourceImpl(ResourceResolver resourceResolver, Node node) { super(resourceResolver, node); this.node = node; } @Override public Iterator<Resource> listChildren() { return getChildren().iterator(); } @Override public Iterable<Resource> getChildren() { try { List<Resource> children = new ArrayList<>(); for (Node child : JcrUtils.getChildNodes(node)) children.add(resourceResolver.getResource(this, child.getName())); return children; } catch (RepositoryException re) { return new ArrayList<>(); } } @Override public Resource getChild(String relPath) { try { return resourceResolver.getResource(Paths.resolve(node.getPath(), relPath)); } catch (RepositoryException re) { throw new SlingRepositoryException(re); } } @Override public String getResourceType() { try { return getResourceTypeForNode(node); } catch (RepositoryException re) { return null; /* ignore */ } } @Override public String getResourceSuperType() { return null; //TODO: implement resource supertypes } @Override public boolean hasChildren() { return listChildren().hasNext(); } @Override public ValueMap getValueMap() { return this.adaptTo(ValueMap.class); } @Override @SuppressWarnings({"unchecked", "deprecation"}) public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) { if (type.equals(Node.class)) return (AdapterType)node; if (type.equals(ValueMap.class) || type.equals(Map.class)) return (AdapterType)new JcrPropertyMap(node); if (type.equals(PersistableValueMap.class)) return (AdapterType)new JcrModifiablePropertyMap(node); if (type.equals(ModifiableValueMap.class)) return (AdapterType)new JcrModifiableValueMap(node, null); if (type.equals(Page.class)) { try { ValueMap properties = this.adaptTo(ValueMap.class); if (properties == null) return null; String primaryType = properties.get(JCR_PRIMARYTYPE, String.class); if (primaryType == null || !primaryType.equals(JcrConstants.CQ_PAGE)) return null; if (!node.hasNode(JCR_CONTENT)) return null; return (AdapterType)new PageImpl(new NodeResourceImpl(resourceResolver, node)); } catch (RepositoryException e) { return null; } } if (type.equals(Asset.class)) { try { ValueMap properties = ResourceUtil.getValueMap(this); return !"dam:Asset".equals(properties.get(JCR_PRIMARYTYPE, String.class)) ? null : !node.hasNode(JCR_CONTENT) ? null : (AdapterType)new AssetImpl(this); } catch (RepositoryException e) { return null; } } if (type.equals(InputStream.class)) { try { Node content = node.isNodeType(NT_FILE) ? node.getNode(JCR_CONTENT) : node; Property data = content.hasProperty(JCR_DATA) ? content.getProperty(JCR_DATA) : null; return data != null ? (AdapterType)data.getBinary().getStream() : null; } catch (RepositoryException e) { return null; } } return super.adaptTo(type); } }