org.alfresco.extension.countersign.action.executer.AbstractSignatureActionExecuter.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.extension.countersign.action.executer.AbstractSignatureActionExecuter.java

Source

/*
 * Copyright 2012-2013 Alfresco Software Limited.
 * 
 * Licensed under the GNU Affero General Public License, Version 3.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.gnu.org/licenses/agpl-3.0.html
 * 
 * If you do not wish to be bound to the terms of the AGPL v3.0, 
 * A commercial license may be obtained by contacting the author.
 * 
 * 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.
 * 
 * This file is part of an unsupported extension to Alfresco.
 * 
 */
package org.alfresco.extension.countersign.action.executer;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;

import org.alfresco.extension.countersign.model.CounterSignSignatureModel;
import org.alfresco.extension.countersign.signature.SignatureProviderFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.model.filefolder.HiddenAspect;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.json.simple.JSONObject;

import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;

public abstract class AbstractSignatureActionExecuter extends ActionExecuterAbstractBase {

    /**
     * Predefined position options
     */
    public static final String POSITION_CENTER = "center";
    public static final String POSITION_TOPLEFT = "topleft";
    public static final String POSITION_TOPRIGHT = "topright";
    public static final String POSITION_BOTTOMLEFT = "bottomleft";
    public static final String POSITION_BOTTOMRIGHT = "bottomright";

    protected ServiceRegistry serviceRegistry;

    public static final String PARAM_LOCATION = "location";
    public static final String PARAM_GEOLOCATION = "geolocation";
    public static final String PARAM_REASON = "reason";
    public static final String PARAM_KEY_PASSWORD = "key-password";

    protected String alias = "countersign";

    protected SignatureProviderFactory signatureProviderFactory = null;

    /**
     * Load the parameter definitions common across all signature types
     *
     */
    protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
        paramList.add(new ParameterDefinitionImpl(PARAM_LOCATION, DataTypeDefinition.TEXT, false,
                getParamDisplayLabel(PARAM_LOCATION)));
        paramList.add(new ParameterDefinitionImpl(PARAM_GEOLOCATION, DataTypeDefinition.TEXT, false,
                getParamDisplayLabel(PARAM_GEOLOCATION)));
        paramList.add(new ParameterDefinitionImpl(PARAM_REASON, DataTypeDefinition.TEXT, false,
                getParamDisplayLabel(PARAM_REASON)));
        paramList.add(new ParameterDefinitionImpl(PARAM_KEY_PASSWORD, DataTypeDefinition.TEXT, true,
                getParamDisplayLabel(PARAM_KEY_PASSWORD)));
    }

    /**
     * Get the signature block position, using the provided JSON for the box coordinates
     * and the selected page
     * 
     * @param pageRect
     * @param box
     * @return
     */
    protected Rectangle positionBlock(Rectangle pageRect, JSONObject box) {
        float startX = Float.parseFloat(String.valueOf(box.get("startX")));
        float startY = Float.parseFloat(String.valueOf(box.get("startY")));
        float endX = Float.parseFloat(String.valueOf(box.get("endX")));
        float endY = Float.parseFloat(String.valueOf(box.get("endY")));

        // make sure that the ll and ur coordinates match iText's expectations
        startY = pageRect.getHeight() - startY;
        endY = pageRect.getHeight() - endY;

        // create the rectangle to contain the signature from the corrected coordinates
        Rectangle r = new Rectangle(startX, startY, endX, endY);

        return r;
    }

    /**
     * @param actionedUponNodeRef
     * @return
     */
    protected ContentReader getReader(NodeRef nodeRef) {
        // First check that the node is a sub-type of content
        QName typeQName = serviceRegistry.getNodeService().getType(nodeRef);
        if (serviceRegistry.getDictionaryService().isSubClass(typeQName, ContentModel.TYPE_CONTENT) == false) {
            // it is not content, so can't transform
            return null;
        }

        // Get the content reader
        ContentReader contentReader = serviceRegistry.getContentService().getReader(nodeRef,
                ContentModel.PROP_CONTENT);

        return contentReader;
    }

    /**
     * Gets the X value for centering the signature stamp
     * 
     * @param r
     * @param img
     * @return
     */
    protected float getCenterX(Rectangle r, Image img) {
        float x = 0;
        float pdfwidth = r.getWidth();
        float imgwidth = img.getWidth();

        x = (pdfwidth - imgwidth) / 2;

        return x;
    }

    /**
     * Gets the Y value for centering the signature stamp
     * 
     * @param r
     * @param img
     * @return
     */
    protected float getCenterY(Rectangle r, Image img) {
        float y = 0;
        float pdfheight = r.getHeight();
        float imgheight = img.getHeight();

        y = (pdfheight - imgheight) / 2;

        return y;
    }

    /**
     * Create a rectangle for the visible stamp using the selected position and block size
     * 
     * @param position
     * @param width
     * @param height
     * @return
     */
    protected Rectangle positionBlock(String position, Rectangle pageRect, int width, int height) {

        float pageHeight = pageRect.getHeight();
        float pageWidth = pageRect.getWidth();

        Rectangle r = null;
        //Rectangle constructor(float llx, float lly, float urx, float ury)
        if (position.equals(POSITION_BOTTOMLEFT)) {
            r = new Rectangle(0, height, width, 0);
        } else if (position.equals(POSITION_BOTTOMRIGHT)) {
            r = new Rectangle(pageWidth - width, height, pageWidth, 0);
        } else if (position.equals(POSITION_TOPLEFT)) {
            r = new Rectangle(0, pageHeight, width, pageHeight - height);
        } else if (position.equals(POSITION_TOPRIGHT)) {
            r = new Rectangle(pageWidth - width, pageHeight, pageWidth, pageHeight - height);
        } else if (position.equals(POSITION_CENTER)) {
            r = new Rectangle((pageWidth / 2) - (width / 2), (pageHeight / 2) - (height / 2),
                    (pageWidth / 2) + (width / 2), (pageHeight / 2) + (height / 2));
        }

        return r;
    }

    /**
     * Creates a "signature" object and associates it with the signed doc
     * @param node
     * @param location
     * @param reason
     */
    protected NodeRef addSignatureNodeAssociation(NodeRef node, String location, String reason,
            String signatureField, java.util.Date sigDate, String geolocation, int page, String position) {
        NodeService nodeService = serviceRegistry.getNodeService();

        String userId = AuthenticationUtil.getRunAsUser();
        NodeRef person = serviceRegistry.getPersonService().getPerson(userId);

        // if page is -1, then this was a signature field, set position to "none"
        if (page == -1)
            position = "none";

        HashMap<QName, Serializable> props = new HashMap<QName, Serializable>();
        props.put(CounterSignSignatureModel.PROP_REASON, reason);
        props.put(CounterSignSignatureModel.PROP_LOCATION, location);
        props.put(CounterSignSignatureModel.PROP_SIGNATUREDATE, sigDate);
        props.put(CounterSignSignatureModel.PROP_SIGNATUREFIELD, signatureField);
        props.put(CounterSignSignatureModel.PROP_SIGNATUREPAGE, page);
        props.put(CounterSignSignatureModel.PROP_SIGNATUREPOSITION, position);
        props.put(CounterSignSignatureModel.PROP_EXTERNALSIGNER, userId);

        // check the geolocation data, if it is valid, split it out and add
        if (geolocation.indexOf(",") != -1) {
            String[] latLong = geolocation.split(",");
            props.put(ContentModel.PROP_LATITUDE, latLong[0]);
            props.put(ContentModel.PROP_LONGITUDE, latLong[1]);
        } else {
            props.put(ContentModel.PROP_LATITUDE, -1);
            props.put(ContentModel.PROP_LONGITUDE, -1);
        }

        QName assocQName = QName.createQName(CounterSignSignatureModel.COUNTERSIGN_SIGNATURE_MODEL_1_0_URI,
                QName.createValidLocalName(userId + "-" + sigDate.getTime()));

        ChildAssociationRef sigChildRef = nodeService.createNode(node, CounterSignSignatureModel.ASSOC_SIGNATURES,
                assocQName, CounterSignSignatureModel.TYPE_SIGNATURE, props);

        NodeRef signature = sigChildRef.getChildRef();

        // add hidden aspect to signature nodes, these should not be 
        // shown in any document lists or other Share views
        HashMap<QName, Serializable> aspectProps = new HashMap<QName, Serializable>();
        aspectProps.put(ContentModel.PROP_VISIBILITY_MASK, HiddenAspect.Visibility.NotVisible.getMask());
        nodeService.addAspect(signature, ContentModel.ASPECT_HIDDEN, aspectProps);

        nodeService.createAssociation(signature, person, CounterSignSignatureModel.ASSOC_SIGNEDBY);

        return signature;
    }

    /**
     * Sets the signature provider used to sign documents without the need to select
     * a keystore, etc.
     * 
     * @param signatureProvider
     */
    public void setSignatureProviderFactory(SignatureProviderFactory signatureProviderFactory) {
        this.signatureProviderFactory = signatureProviderFactory;
    }

    public void setServiceRegistry(ServiceRegistry serviceRegistry) {
        this.serviceRegistry = serviceRegistry;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }
}