| /* |
| * 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.jackrabbit.vault.fs.impl.aggregator; |
| |
| import java.util.Collection; |
| |
| import javax.jcr.Node; |
| import javax.jcr.Property; |
| import javax.jcr.RepositoryException; |
| |
| import org.apache.jackrabbit.vault.fs.api.Aggregate; |
| import org.apache.jackrabbit.vault.fs.api.Aggregator; |
| import org.apache.jackrabbit.vault.fs.api.Artifact; |
| import org.apache.jackrabbit.vault.fs.api.ArtifactSet; |
| import org.apache.jackrabbit.vault.fs.api.ArtifactType; |
| import org.apache.jackrabbit.vault.fs.api.DumpContext; |
| import org.apache.jackrabbit.vault.fs.api.Dumpable; |
| import org.apache.jackrabbit.vault.fs.api.ImportInfo; |
| import org.apache.jackrabbit.vault.fs.api.ItemFilterSet; |
| import org.apache.jackrabbit.vault.fs.impl.ArtifactSetImpl; |
| import org.apache.jackrabbit.vault.fs.impl.DirectoryArtifact; |
| import org.apache.jackrabbit.vault.fs.impl.io.DocViewSerializer; |
| import org.apache.jackrabbit.vault.fs.impl.io.ImportInfoImpl; |
| import org.apache.jackrabbit.vault.fs.io.Serializer; |
| import org.apache.jackrabbit.vault.fs.spi.ACLManagement; |
| import org.apache.jackrabbit.vault.fs.spi.ServiceProviderFactory; |
| import org.apache.jackrabbit.vault.util.Constants; |
| import org.apache.jackrabbit.vault.util.PathUtil; |
| |
| /** |
| */ |
| public class GenericAggregator implements Aggregator, Dumpable { |
| |
| /** |
| * name hint for the aggregator |
| */ |
| private String name; |
| |
| /** |
| * flag indicating if this aggregator aggregates children |
| */ |
| private boolean fullCoverage = false; |
| |
| /** |
| * filter that regulates what to be included in the aggregate |
| */ |
| private final ItemFilterSet contentFilter = new ItemFilterSet(); |
| |
| /** |
| * filter that regulates if this aggregator is to be used |
| */ |
| private final ItemFilterSet matchFilter = new ItemFilterSet(); |
| |
| /** |
| * the 'default' aggregator flag |
| */ |
| private boolean isDefault = false; |
| |
| /** |
| * acl management |
| */ |
| private ACLManagement aclManagement; |
| |
| private ACLManagement getAclManagement() { |
| if (aclManagement == null) { |
| aclManagement = ServiceProviderFactory.getProvider().getACLManagement(); |
| } |
| return aclManagement; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean hasFullCoverage() { |
| return fullCoverage; |
| } |
| |
| public void setHasFullCoverage(String hasFullCoverage) { |
| this.fullCoverage = Boolean.valueOf(hasFullCoverage); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isDefault() { |
| return isDefault; |
| } |
| |
| /** |
| * Sets the default flag |
| * @param aDefault the default flag |
| */ |
| public void setIsDefault(String aDefault) { |
| isDefault = Boolean.valueOf(aDefault); |
| } |
| |
| /** |
| * Returns the name of this aggregator |
| * @return the name |
| */ |
| public String getName() { |
| return name; |
| } |
| |
| /** |
| * Sets the name of this aggregator |
| * @param name the name |
| */ |
| public void setName(String name) { |
| this.name = name; |
| } |
| |
| |
| /** |
| * Sets the flag indicating if this aggregator aggregates children |
| * |
| * @param fullCoverage {@code true} if this aggregator aggregates |
| * children |
| */ |
| public void setFullCoverage(String fullCoverage) { |
| this.fullCoverage = Boolean.valueOf(fullCoverage); |
| } |
| |
| |
| /** |
| * Returns the content filter |
| * @return the content filter |
| */ |
| public ItemFilterSet getContentFilter() { |
| return contentFilter; |
| } |
| |
| /** |
| * Returns the match filter |
| * @return the match filter |
| */ |
| public ItemFilterSet getMatchFilter() { |
| return matchFilter; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean includes(Node root, Node node, String path) throws RepositoryException { |
| if (path == null) { |
| path = node.getPath(); |
| } |
| return contentFilter.contains(node, path, PathUtil.getDepth(path) - root.getDepth()); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean matches(Node node, String path) throws RepositoryException { |
| return matchFilter.contains(node, path, 0); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean includes(Node root, Node parent, Property property, String path) throws RepositoryException { |
| if (path == null) { |
| path = property.getPath(); |
| } |
| return contentFilter.contains(property, path, PathUtil.getDepth(path) - root.getDepth()); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public ArtifactSet createArtifacts(Aggregate aggregate) throws RepositoryException { |
| ArtifactSetImpl artifacts = new ArtifactSetImpl(); |
| |
| // set coverage filter to artifacts |
| artifacts.setCoverage(getContentFilter()); |
| |
| // add directory |
| ArtifactType type = ArtifactType.PRIMARY; |
| String name = aggregate.getName(); |
| String ext = ".xml"; |
| Artifact parent = null; |
| if (!hasFullCoverage()) { |
| parent = new DirectoryArtifact(name); |
| artifacts.add(parent); |
| name = ""; |
| ext = Constants.DOT_CONTENT_XML; |
| // special optimization if only nt:folder |
| if ("nt:folder".equals(aggregate.getNode().getPrimaryNodeType().getName()) |
| && aggregate.getNode().getMixinNodeTypes().length == 0) { |
| return artifacts; |
| } |
| } |
| |
| // add extra |
| Serializer ser = new DocViewSerializer(aggregate); |
| artifacts.add(parent, name, ext, type, ser, 0); |
| |
| // add binaries |
| Collection<Property> bins = aggregate.getBinaries(); |
| if (bins != null && !bins.isEmpty()) { |
| if (hasFullCoverage()) { |
| assert parent == null; |
| parent = new DirectoryArtifact(aggregate.getName()); |
| artifacts.add(parent); |
| } |
| int pathLen = aggregate.getPath().length(); |
| if (pathLen > 1) { |
| pathLen++; |
| } |
| for (Property prop: bins) { |
| String relPath = prop.getPath().substring(pathLen); |
| artifacts.add(parent, relPath, ".binary", ArtifactType.BINARY, prop, 0); |
| } |
| |
| } |
| return artifacts; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * Throws an exception if this aggregator allows children but |
| * {@code recursive} is {@code false}. |
| */ |
| public ImportInfo remove(Node node, boolean recursive, boolean trySave) |
| throws RepositoryException { |
| if (fullCoverage && !recursive) { |
| // todo: allow smarter removal |
| throw new RepositoryException("Unable to remove content since aggregation has children and recursive is not set."); |
| } |
| ImportInfo info = new ImportInfoImpl(); |
| info.onDeleted(node.getPath()); |
| Node parent = node.getParent(); |
| if (getAclManagement().isACLNode(node)) { |
| getAclManagement().clearACL(parent); |
| } else { |
| node.remove(); |
| } |
| if (trySave) { |
| parent.getSession().save(); |
| } |
| return info; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void dump(DumpContext ctx, boolean isLast) { |
| ctx.println(isLast, getClass().getSimpleName()); |
| ctx.indent(isLast); |
| ctx.printf(false, "name: %s", getName()); |
| ctx.printf(false, "fullCoverage: %b", hasFullCoverage()); |
| ctx.printf(false, "default: %b", isDefault()); |
| ctx.println(false, "Content Filter"); |
| ctx.indent(false); |
| getContentFilter().dump(ctx, true); |
| ctx.outdent(); |
| ctx.println(true, "Match Filter"); |
| ctx.indent(true); |
| getMatchFilter().dump(ctx, true); |
| ctx.outdent(); |
| ctx.outdent(); |
| } |
| |
| } |