/* * 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.pipes; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ValueMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * provides generic utilities for a pipe, is also a dummy pipe (outputs its input, without changing anything) */ public class BasePipe implements Pipe { private final Logger logger = LoggerFactory.getLogger(BasePipe.class); public static final String RESOURCE_TYPE = "slingPipes/base"; public static final String DRYRUN_KEY = "dryRun"; protected static final String DRYRUN_EXPR = "${" + DRYRUN_KEY + "}"; protected ResourceResolver resolver; protected ValueMap properties; protected Resource resource; protected ContainerPipe parent; protected String distributionAgent; protected PipeBindings bindings; protected ReferencePipe referrer; // used by pipes using complex JCR configurations public static final List<String> IGNORED_PROPERTIES = Arrays.asList(new String[]{"jcr:lastModified", "jcr:primaryType", "jcr:created", "jcr:createdBy"}); protected Boolean dryRunObject; @Override public ContainerPipe getParent() { return parent; } @Override public void setParent(ContainerPipe parent) { this.parent = parent; } protected Plumber plumber; private String name; /** * Pipe Constructor * @param plumber plumber * @param resource configuration resource * @throws Exception in case configuration is not working */ public BasePipe(Plumber plumber, Resource resource) throws Exception { this.resource = resource; properties = resource.adaptTo(ValueMap.class); resolver = resource.getResourceResolver(); this.plumber = plumber; name = properties.get(PN_NAME, resource.getName()); distributionAgent = properties.get(PN_DISTRIBUTION_AGENT, String.class); bindings = new PipeBindings(resource); } @Override public boolean isDryRun() { if (dryRunObject == null) { Object run = bindings.isBindingDefined(DRYRUN_KEY) ? bindings.instantiateObject(DRYRUN_EXPR) : false; dryRunObject = run != null && run instanceof Boolean ? (Boolean)run : false; } boolean dryRun = dryRunObject != null ? dryRunObject : false; return dryRun; } @Override public String toString() { return name + " " + "(path: " + resource.getPath() + ", dryRun: " + isDryRun() + ", modifiesContent: " + modifiesContent() + ")"; } @Override public boolean modifiesContent() { return false; } @Override public String getName(){ return name; } /** * Get pipe's expression, instanciated or not * @return configured expression */ public String getExpr(){ String rawExpression = properties.get(PN_EXPR, ""); return bindings.instantiateExpression(rawExpression); } /** * Get pipe's path, instanciated or not * @return configured path (can be empty) */ public String getPath() { String rawPath = properties.get(PN_PATH, ""); return bindings.instantiateExpression(rawPath); } @Override public Resource getConfiguredInput() { Resource configuredInput = null; String path = getPath(); if (StringUtils.isNotBlank(path)){ configuredInput = resolver.getResource(path); if (configuredInput == null) { logger.warn("configured path {} is not found, expect some troubles...", path); } } return configuredInput; } /** * Retrieves previous pipe if contained by a parent, or referrer's * @return pipe before this one or the referrer's can be null in case there is no parent */ protected Pipe getPreviousPipe(){ return referrer == null ? (parent != null ? parent.getPreviousPipe(this) : null) : referrer.getPreviousPipe(); } @Override public Resource getInput() { Resource resource = getConfiguredInput(); if (resource == null && parent != null){ Pipe previousPipe = getPreviousPipe(); if (previousPipe != null) { return bindings.getExecutedResource(previousPipe.getName()); } } return resource; } @Override public Object getOutputBinding() { if (parent != null){ Resource resource = bindings.getExecutedResource(getName()); if (resource != null) { return resource.adaptTo(ValueMap.class); } } return null; } @Override public PipeBindings getBindings() { return bindings; } @Override public void setBindings(PipeBindings bindings) { this.bindings = bindings; } /** * default execution, just returns current resource * @return output of this pipe, which is here the input resource */ public Iterator<Resource> getOutput(){ Resource resource = getInput(); if (resource != null){ return Collections.singleton(resource).iterator(); } return EMPTY_ITERATOR; } /** * Get configuration node * @return configuration node if any */ public Resource getConfiguration() { return resource.getChild(NN_CONF); } @Override public String getDistributionAgent() { return distributionAgent; } @Override public void setReferrer(ReferencePipe pipe) { referrer = pipe; } /** * Empty resource iterator */ public static final Iterator<Resource> EMPTY_ITERATOR = Collections.emptyIterator(); }