diff options
94 files changed, 5970 insertions, 1 deletions
| diff --git a/pdf-as-cli/.gitignore b/pdf-as-cli/.gitignore new file mode 100644 index 00000000..5e56e040 --- /dev/null +++ b/pdf-as-cli/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/pdf-as-cli/build.gradle b/pdf-as-cli/build.gradle new file mode 100644 index 00000000..48a9b659 --- /dev/null +++ b/pdf-as-cli/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'java' +apply plugin: 'eclipse' + +jar { +    manifest { +        attributes 'Implementation-Title': 'PDF-AS CLI', 'Implementation-Version': version +    } +} + +repositories { +    mavenCentral() +} + +dependencies { +	compile project (':pdf-as-lib') +	compile project (':stamper:stmp-itext') +    compile group: 'commons-collections', name: 'commons-collections', version: '3.2' +    testCompile group: 'junit', name: 'junit', version: '4.+' +} + +test { +    systemProperties 'property': 'value' +} + +uploadArchives { +    repositories { +       flatDir { +           dirs 'repos' +       } +    } +} diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java new file mode 100644 index 00000000..6e0118e4 --- /dev/null +++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java @@ -0,0 +1,41 @@ +package at.gv.egiz.pdfas.cli; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.utils.StreamUtils; +import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.PdfAs; +import at.gv.egiz.pdfas.lib.api.PdfAsFactory; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; + +public class DeveloperMain { + +	public static void main(String[] args) {		 +		String user_home = System.getProperty("user.home"); +		String pdfas_dir = user_home + File.separator + "PDF-AS"; +		PdfAs pdfas = PdfAsFactory.createPdfAs(new File(pdfas_dir)); +		Configuration config = pdfas.getConfiguration(); +		 +		byte[] data; +		try { +			data = StreamUtils.inputStreamToByteArray(new FileInputStream("/home/afitzek/devel/pdfas_neu/simple.pdf")); +			SignParameter parameter = new SignParameter(config, new ByteArrayDataSource(data)); +			pdfas.sign(parameter); +		} catch (FileNotFoundException e1) { +			// TODO Auto-generated catch block +			e1.printStackTrace(); +		} catch (IOException e1) { +			// TODO Auto-generated catch block +			e1.printStackTrace(); +		}catch (PdfAsException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		} +	} + +} diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java new file mode 100644 index 00000000..6dbf3f3e --- /dev/null +++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.cli;
\ No newline at end of file diff --git a/pdf-as-common/.gitignore b/pdf-as-common/.gitignore new file mode 100644 index 00000000..5e56e040 --- /dev/null +++ b/pdf-as-common/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/pdf-as-common/build.gradle b/pdf-as-common/build.gradle new file mode 100644 index 00000000..19d3dc90 --- /dev/null +++ b/pdf-as-common/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'java' +apply plugin: 'eclipse' + +jar { +    manifest { +        attributes 'Implementation-Title': 'PDF-AS-4 Commons', 'Implementation-Version': version +    } +} + +repositories { +    mavenCentral() +} + +dependencies { +	compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.5' +	compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2' +    compile group: 'commons-collections', name: 'commons-collections', version: '3.2' +	compile group: 'ognl', name: 'ognl', version: '3.0.6' +    testCompile group: 'junit', name: 'junit', version: '4.+' +} + +test { +    systemProperties 'property': 'value' +} + +uploadArchives { +    repositories { +       flatDir { +           dirs 'repos' +       } +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java new file mode 100644 index 00000000..57c1e7ab --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java @@ -0,0 +1,20 @@ +package at.gv.egiz.pdfas.common.exceptions; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/28/13 + * Time: 12:04 PM + * To change this template use File | Settings | File Templates. + */ +public class PDFIOException extends PdfAsException { + +    public PDFIOException(String msgId) { +        super(msgId); +    } + + +    public PDFIOException(String msgId, Throwable e) { +        super(msgId, e); +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java new file mode 100644 index 00000000..e36aa082 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java @@ -0,0 +1,31 @@ +package at.gv.egiz.pdfas.common.exceptions; + +import at.gv.egiz.pdfas.common.messages.MessageResolver; + +public class PdfAsException extends Exception { +	public PdfAsException() { +        super(); +    } + +    public PdfAsException(String msgId) { +        super(msgId); +    } + +    public PdfAsException(String msgId, Throwable e) { +        super(msgId, e); +    } + +    @Override +    public String getMessage() { +        return localizeMessage(super.getMessage()); +    } + +    @Override +    public String getLocalizedMessage() { +        return localizeMessage(super.getMessage()); +    } + +    protected String localizeMessage(String msgId) { +        return MessageResolver.resolveMessage(msgId); +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java new file mode 100644 index 00000000..431ffa5d --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java @@ -0,0 +1,20 @@ +package at.gv.egiz.pdfas.common.exceptions; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/10/13 + * Time: 10:54 AM + * To change this template use File | Settings | File Templates. + */ +public class PdfAsSettingsException extends PdfAsException { + +    public PdfAsSettingsException(String msgId) { +        super(msgId); +    } + + +    public PdfAsSettingsException(String msgId, Throwable e) { +        super(msgId, e); +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java new file mode 100644 index 00000000..cfd6a993 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.exceptions;
\ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java new file mode 100644 index 00000000..0bc1bab7 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java @@ -0,0 +1,42 @@ +package at.gv.egiz.pdfas.common.messages; + +import java.util.Locale; +import java.util.ResourceBundle; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MessageResolver { +	private static final String messageResource = "resources.messages.common"; +    private static final String missingMsg = "Please add message "; + +    private static final Logger logger = LoggerFactory.getLogger(MessageResolver.class); + +    private static ResourceBundle bundle; + +    static { +        ResourceBundle bundle = ResourceBundle.getBundle(messageResource); +        if(bundle == null) { +            logger.error("Failed to load resource bundle!!"); +            Runtime.getRuntime().exit(-1); +        } +    } + +    public static void forceLocale(Locale locale) { +        bundle = ResourceBundle.getBundle(messageResource, locale); +    } + +    public static String resolveMessage(String msgId) { +        if(bundle == null) { +            return missingMsg + msgId; +        } +        if(bundle.containsKey(msgId)) { +            String value = bundle.getString(msgId); +            if(value == null) { +                return missingMsg + msgId; +            } +            return value; +        } +        return missingMsg + msgId; +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java new file mode 100644 index 00000000..0ac78c22 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.messages;
\ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java new file mode 100644 index 00000000..58c99dad --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common;
\ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java new file mode 100644 index 00000000..2e2ee024 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java @@ -0,0 +1,65 @@ +package at.gv.egiz.pdfas.common.settings; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/10/13 + * Time: 12:58 PM + * To change this template use File | Settings | File Templates. + */ +public interface IProfileConstants { +    /** +     * The settings key prefix for signature definitions. <code>"sig_obj."</code> +     */ +    public static final String SIG_OBJ = "sig_obj."; + +    public static final String SIG_DATE = "SIG_DATE"; + +    /** +     * The settings key prefix for the signature table object definition +     */ +    public static final String TABLE = "table."; + +    /** +     * The settings value refering to a table +     */ +    public final static String TYPE_TABLE = "TABLE"; + +    /** +     * The settings value refering to an image +     */ +    public final static String TYPE_IMAGE = "i"; + +    /** +     * The settings value refering to a text caption +     */ +    public final static String TYPE_CAPTION = "c"; + +    /** +     * The settings value refering to a text value +     */ +    public final static String TYPE_VALUE = "v"; + +    /** +     * The settings key sub prefix getting the width of columns for a table +     * definition +     */ +    public final static String COLS_WITH = "ColsWidth"; + +    /** +     * The settings key sub prefix getting the style definition +     */ +    public final static String STYLE = "Style"; + +    public final static String PROFILE_VALUE = "value"; + +    public final static String PROFILE_KEY = "key"; + +    public final static String KEY_SEPARATOR = "."; +     +    public final static String INCLUDE = "include"; +     +    public final static String CFG_DIR = "cfg"; +    public final static String CFG_FILE = "config.properties"; +     +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java new file mode 100644 index 00000000..9e3291d2 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.common.settings; + +import java.util.Map; +import java.util.Vector; + +public interface ISettings { +	public String getValue(String key); +	public boolean hasValue(String key); +	public boolean hasPrefix(String prefix); +	public Map<String, String> getValuesPrefix(String prefix); +	public Vector<String> getFirstLevelKeys(String prefix); +	public String getWorkingDirectory(); +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java new file mode 100644 index 00000000..da946215 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java @@ -0,0 +1,124 @@ +package at.gv.egiz.pdfas.common.settings; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; + +public class Settings implements ISettings, IProfileConstants{ + +    private static final Logger logger = LoggerFactory.getLogger(Settings.class); + +    protected Properties properties = new Properties(); + +    protected File workDirectory; +     +    public Settings(File workDirectory) { +        try { +        	this.workDirectory = workDirectory; +            loadSettings(workDirectory); +        } catch (PdfAsSettingsException e) { +            logger.error(e.getMessage(), e); +        } +    } + +    public void loadSettings(File workDirectory) throws PdfAsSettingsException { +        try { +        	 +        	String configDir = workDirectory.getAbsolutePath() + File.separator + CFG_DIR; +        	String configFile = configDir + File.separator + CFG_FILE; +        	logger.debug("Loading cfg file: " + configFile); +            properties.load(new FileInputStream(configFile)); +             +            Map<String, String> includes = this.getValuesPrefix(INCLUDE); +             +            if(includes != null) { +            	Iterator<String> includeIterator = includes.values().iterator(); +            	while(includeIterator.hasNext()) { +            		String includeFile = configDir + File.separator + includeIterator.next(); +            		logger.debug("Loading included cfg file: " + includeFile); +            		properties.load(new FileInputStream(includeFile)); +            	} +            } +             +            logger.debug("Configured Properties:"); +            if(logger.isDebugEnabled()) { +            	properties.list(System.out); +            } +             +        } catch (IOException e) { +            throw new PdfAsSettingsException("Failed to read settings!", e); +        } +    } + +    public String getValue(String key) { +        return properties.getProperty(key); +    } + +    public boolean hasValue(String key) { +        return properties.containsKey(key); +    } + +    public Map<String, String> getValuesPrefix(String prefix) { +        Iterator<Object> keyIterator = properties.keySet().iterator(); +        Map<String, String> valueMap = new HashMap<String, String>(); +        while(keyIterator.hasNext()) { +            String key = keyIterator.next().toString(); + +            if(key.startsWith(prefix)) { +                valueMap.put(key, properties.getProperty(key)); +            } +        } + +        if(valueMap.isEmpty()) { +            return null; +        } + +        return valueMap; +    } + +    public Vector<String> getFirstLevelKeys(String prefix) { +        String mPrefix = prefix.endsWith(".")?prefix:prefix+"."; +        Iterator<Object> keyIterator = properties.keySet().iterator(); +        Vector<String> valueMap = new Vector<String>(); +        while(keyIterator.hasNext()) { +            String key = keyIterator.next().toString(); + +            if(key.startsWith(prefix)) { +                int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ?  key.indexOf('.', mPrefix.length()) : key.length(); +                String firstLevels = key.substring(0, keyIdx); +                if(!valueMap.contains(firstLevels)) { +                    valueMap.add(firstLevels); +                } +            } +        } + +        if(valueMap.isEmpty()) { +            return null; +        } + +        return valueMap; +    } + +	public boolean hasPrefix(String prefix) { +		Iterator<Object> keyIterator = properties.keySet().iterator(); +        while(keyIterator.hasNext()) { +            String key = keyIterator.next().toString(); + +            if(key.startsWith(prefix)) { +                return true; +            } +        } +        return false; +	} + +	public String getWorkingDirectory() { +		return this.workDirectory.getAbsolutePath(); +	} + +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java new file mode 100644 index 00000000..3df929b1 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java @@ -0,0 +1,39 @@ +package at.gv.egiz.pdfas.common.settings; + +public class SignatureProfileEntry { +    private String key = null; +    private String caption = null; +    private String value = null; + +    public SignatureProfileEntry() { +    } + +    public String getKey() { +        return key; +    } + +    public void setKey(String key) { +        this.key = key; +    } + +    public String getCaption() { +        return caption; +    } + +    public void setCaption(String caption) { +        this.caption = caption; +    } + +    public String getValue() { +        return value; +    } + +    public void setValue(String value) { +        this.value = value; +    } + +    @Override +    public String toString() { +        return getKey() + "[ " + getCaption() + " : " + getValue() + " ]"; +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java new file mode 100644 index 00000000..46f2ed09 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java @@ -0,0 +1,121 @@ +package at.gv.egiz.pdfas.common.settings; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +public class SignatureProfileSettings implements IProfileConstants { + +    private static final Logger logger = LoggerFactory.getLogger(SignatureProfileSettings.class); + +    private Map<String, SignatureProfileEntry> profileInformations = new HashMap<String, SignatureProfileEntry>(); + +    private Map<String, String> profileSettings = new HashMap<String, String>(); + +    private String profileID; + +    public SignatureProfileSettings(String profileID, ISettings configuration) { +        this.profileID = profileID; +        String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR; +        String keysPrefix = profilePrefix + PROFILE_KEY; +        String valuesPrefix = profilePrefix + PROFILE_VALUE; +        String tablePrefix = profilePrefix + TABLE; + +        logger.debug("Reading Profile: " + profileID); +        logger.debug("Keys Prefix: " + keysPrefix); +        logger.debug("Values Prefix: " + valuesPrefix); +        logger.debug("Table Prefix: " + tablePrefix); + +        Map<String, String> keys = configuration.getValuesPrefix(keysPrefix); +        Map<String, String> values = configuration.getValuesPrefix(valuesPrefix); + +        Iterator<String> keyIterator = keys.keySet().iterator(); + +        while(keyIterator.hasNext()) { +            String key = keyIterator.next(); +            key = key.substring(key.lastIndexOf('.') + 1); +            String valueKey = keys.get(keysPrefix + KEY_SEPARATOR + key); + +            String valueValue = values.get(valuesPrefix + KEY_SEPARATOR + key); + + +            SignatureProfileEntry entry = new SignatureProfileEntry(); +            entry.setKey(key); +            entry.setCaption(valueKey); +            entry.setValue(valueValue); +            profileInformations.put(key, entry); +            logger.debug("   " + entry.toString()); +        } + +        // Find entries where only values exists +        Iterator<String> valuesIterator = values.keySet().iterator(); + +        while(valuesIterator.hasNext()) { +            String key = valuesIterator.next(); +            key = key.substring(key.lastIndexOf('.') + 1); + +            String valueValue = values.get(valuesPrefix + KEY_SEPARATOR + key); + +            SignatureProfileEntry entry = profileInformations.get(key); +            if(entry == null) { +                entry = new SignatureProfileEntry(); +                entry.setKey(key); +                entry.setCaption(null); +                entry.setValue(valueValue); +                profileInformations.put(key, entry); +            } + +            logger.debug("   " + entry.toString()); +        } + +        Map<String, String> others = configuration.getValuesPrefix(profilePrefix); + +        Iterator<String> otherIterator = others.keySet().iterator(); + +        while(otherIterator.hasNext()) { +            String key = otherIterator.next(); + +            logger.trace("Checking key " + key); +            if( key.startsWith(keysPrefix) || +                key.startsWith(valuesPrefix) || +                key.startsWith(tablePrefix)) { +                continue; +            } + +            String value = others.get(key); +            key = key.substring(key.lastIndexOf('.') + 1); + +            profileSettings.put(key, others.get(value)); + +            logger.debug("   Settings: " + key + " : " + value); +        } +    } + +    public String getCaption(String key) { +        SignatureProfileEntry entry = profileInformations.get(key); +        if(entry != null) { +            return entry.getCaption(); +        } +        return null; +    } + +    public String getValue(String key) { +        SignatureProfileEntry entry = profileInformations.get(key); +        if(entry != null) { +            String value = entry.getValue(); + +            if(value == null) { +                // TODO: try to find default value for key! +            } + +            return value; +        } +        // TODO: try to find default value for key! +        return null; +    } + +    public String getProfileID() { +        return profileID; +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java new file mode 100644 index 00000000..c2b123e2 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.settings;
\ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java new file mode 100644 index 00000000..429151ee --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java @@ -0,0 +1,34 @@ +package at.gv.egiz.pdfas.common.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DNUtils { +	private static final Logger logger = LoggerFactory.getLogger(DNUtils.class); + + +    public static Map<String, String> dnToMap(String dn) throws InvalidNameException { +        Map<String, String> map = new HashMap<String, String>(); + +        LdapName ldapName = new LdapName(dn); + +        Iterator<Rdn> rdnIterator = ldapName.getRdns().iterator(); + +        while(rdnIterator.hasNext()) { +            Rdn rdn = rdnIterator.next(); + +            logger.debug(rdn.getType() + " = " + rdn.getValue().toString()); +            map.put(rdn.getType(), rdn.getValue().toString()); +        } + +        return map; +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java new file mode 100644 index 00000000..e98cb124 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java @@ -0,0 +1,22 @@ +package at.gv.egiz.pdfas.common.utils; + +import ognl.OgnlContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/11/13 + * Time: 1:05 PM + * To change this template use File | Settings | File Templates. + */ +public class OgnlUtils { + +    private static final Logger logger = LoggerFactory.getLogger(OgnlUtils.class); + +    public static String resolvsOgnlExpression(String expression, OgnlContext ctx) { +        // TODO! +        return expression; +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java new file mode 100644 index 00000000..155f9cfb --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java @@ -0,0 +1,94 @@ +package at.gv.egiz.pdfas.common.utils; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + + +public class PDFUtils { + +    private static final Logger logger = LoggerFactory.getLogger(PDFUtils.class); + + +    private static final byte[] signature_pattern = new byte[] { +            (byte) 0x0A, (byte) 0x2F, (byte) 0x43, (byte) 0x6F,   // ./Co +            (byte) 0x6E, (byte) 0x74, (byte) 0x65, (byte) 0x6E,   // nten +            (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x0A,   // ts . +            (byte) 0x2F, (byte) 0x42, (byte) 0x79, (byte) 0x74,   // /Byt +            (byte) 0x65, (byte) 0x52, (byte) 0x61, (byte) 0x6E,   // eRan +            (byte) 0x67, (byte) 0x65, (byte) 0x20, (byte) 0x5B,   // ge [ + +    }; + +    private static final byte range_seperation = (byte) 0x20; +    private static final byte range_end = (byte) 0x5D; + +    private static int extractASCIIInteger(byte[] data, int offset) { +       int nextsepp = nextSeperator(data, offset); + +        if(nextsepp < offset) { +            return -1; +        } + +        String asciiString = new String(data, offset, nextsepp - offset); + +        logger.debug("Extracted " + asciiString); + +        return Integer.parseInt(asciiString); +    } + +    private static int nextSeperator(byte[] data, int offset) { +        for(int i = offset; i < data.length; i++) { +            if(data[i] == range_seperation) { +                return i; +            } else if(data[i] == range_end) { +                return i; +            } +        } +        return -2; +    } + +    public static int[] extractSignatureByteRange(byte[] rawPdfData) { +        int i = 0; +        for(i = rawPdfData.length - 1; i >= 0; i--) { +            if(rawPdfData[i] == signature_pattern[0] && +                    i+signature_pattern.length < rawPdfData.length) { +                boolean match = true; +                for(int j = 0; j < signature_pattern.length; j++) { + +                    if(rawPdfData[i+j] != signature_pattern[j]) { +                        match = false; +                        break; +                    } +                } + +                if(match) { + +                    int offset = i + signature_pattern.length; +                    List<Integer> byteRange = new ArrayList<Integer>(); +                    while(offset > 0) { +                        byteRange.add(extractASCIIInteger(rawPdfData, offset)); +                        offset = nextSeperator(rawPdfData, offset); +                        if(rawPdfData[offset] == range_end) { +                            break; +                        } +                        offset++; +                    } +                    int[] range = new int[byteRange.size()]; +                    for(int j = 0; j < byteRange.size(); j++) { +                        range[j] = byteRange.get(j); +                    } +                    return range; +                } +            } +        } +        return null; +    } + +    public static void checkPDFPermissions(PDDocument doc) { +        // TODO: Check permission for document +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java new file mode 100644 index 00000000..0b15d700 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java @@ -0,0 +1,28 @@ +package at.gv.egiz.pdfas.common.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/29/13 + * Time: 9:54 AM + * To change this template use File | Settings | File Templates. + */ +public class StreamUtils { + +    public static byte[] inputStreamToByteArray(InputStream stream) throws IOException { +        ByteArrayOutputStream bos = new ByteArrayOutputStream(); +        byte[] buffer = new byte[4096]; +        int readBytes = 0; + +        while((readBytes = stream.read(buffer)) != -1) { +            bos.write(buffer, 0, readBytes); +        } +        stream.close(); +        bos.close(); +        return bos.toByteArray(); +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java new file mode 100644 index 00000000..63aae211 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java @@ -0,0 +1,33 @@ +package at.gv.egiz.pdfas.common.utils; + +import java.util.Formatter; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/28/13 + * Time: 12:42 PM + * To change this template use File | Settings | File Templates. + */ +public class StringUtils { + +    public static String bytesToHexString(byte[] bytes) { +        StringBuilder sb = new StringBuilder(bytes.length * 2); + +        Formatter formatter = new Formatter(sb); +        for (byte b : bytes) { +            formatter.format("%02x", b); +        } + +        return sb.toString(); +    } + +    public static String extractLastID(String id) { +        int lastIDX = id.lastIndexOf('.'); +        String result = id; +        if(lastIDX > 0) { +            result = id.substring(lastIDX+1); +        } +        return result; +    } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java new file mode 100644 index 00000000..91b05145 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.utils;
\ No newline at end of file diff --git a/pdf-as-common/src/main/resources/resources/log4j.properties b/pdf-as-common/src/main/resources/resources/log4j.properties new file mode 100644 index 00000000..696db3ef --- /dev/null +++ b/pdf-as-common/src/main/resources/resources/log4j.properties @@ -0,0 +1,15 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=INFO, A1 + +log4j.logger.at.gv.egiz=DEBUG +#log4j.A1.at.gv.egiz=true + +log4j.logger.developer=DEBUG +#log4j.A1.developer=true + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file diff --git a/pdf-as-common/src/main/resources/resources/messages/common.properties b/pdf-as-common/src/main/resources/resources/messages/common.properties new file mode 100644 index 00000000..a2729e21 --- /dev/null +++ b/pdf-as-common/src/main/resources/resources/messages/common.properties @@ -0,0 +1,8 @@ +# PDF Permission Errors +error.pdf.perm.01=You do not have permission to extract images. + +#PDF IO Errors +error.pdf.io.01=Failed to read original PDF Document into PDDocument. + +#Signature errors +error.pdf.sig.01=Failed to create signature!
\ No newline at end of file diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle index 41c9a3ba..b5601f3a 100644 --- a/pdf-as-lib/build.gradle +++ b/pdf-as-lib/build.gradle @@ -12,6 +12,10 @@ repositories {  }  dependencies { +	compile project (':pdf-as-common') +	compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2' +	compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1' +	compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2'      compile group: 'commons-collections', name: 'commons-collections', version: '3.2'      testCompile group: 'junit', name: 'junit', version: '4.+'  } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java new file mode 100644 index 00000000..89acc747 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java @@ -0,0 +1,7 @@ +package at.gv.egiz.pdfas.lib.api; + +public interface Configuration { +	public String getValue(String key); +	public boolean hasValue(String key); +	public void setValue(String key, String value); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java new file mode 100644 index 00000000..9a8d773a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java @@ -0,0 +1,16 @@ +package at.gv.egiz.pdfas.lib.api; + +public interface IConfigurationConstants { + +	public static final String TRUE = "true"; +	 +	public static final String SIG_OBJECT = "sig_obj"; +	public static final String TYPE = "type"; +	public static final String TABLE = "type"; +	public static final String MAIN = "main"; +	public static final String DEFAULT = "default"; +	public static final String SEPERATOR = "."; +	 +	public static final String PLACEHOLDER_SEARCH_ENABLED = "enable_placeholder_search"; +	public static final String DEFAULT_SIGNATURE_PROFILE = SIG_OBJECT + SEPERATOR + TYPE + SEPERATOR + DEFAULT; +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java new file mode 100644 index 00000000..6fea788c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java @@ -0,0 +1,6 @@ +package at.gv.egiz.pdfas.lib.api; + +public interface IDataSource { +	public String getMIMEType(); +    public byte[] getByteData(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java new file mode 100644 index 00000000..4b491064 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java @@ -0,0 +1,40 @@ +package at.gv.egiz.pdfas.lib.api; + +import java.util.List; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.api.sign.SignResult; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; + +public interface PdfAs { + +	// Sign +	// Verify +	// Get Configuration +	 +	/** +	 * Signs a PDF document using PDF-AS. +	 *  +	 * @param parameter +	 * @return +	 */ +	public SignResult sign(SignParameter parameter) throws PdfAsException; +	 +	/** +	 * Verifies a document with (potentially multiple) PDF-AS signatures. +	 *   +	 * @param parameter The verification parameter +	 * @return A list of verification Results +	 */ +	public List<VerifyResult> verify(VerifyParameter parameter); +	 +	/** +	 * Gets a copy of the PDF-AS configuration, to allow the application to  +	 * override configuration parameters at runtime. +	 *  +	 * @return A private copy of the pdf as configuration +	 */ +	public Configuration getConfiguration(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java new file mode 100644 index 00000000..ae9388eb --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java @@ -0,0 +1,9 @@ +package at.gv.egiz.pdfas.lib.api; + +import java.io.File; + +public class PdfAsFactory { +	public static PdfAs createPdfAs(File configuration) { +		return null; +	} +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java new file mode 100644 index 00000000..999c91bc --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java @@ -0,0 +1,32 @@ +package at.gv.egiz.pdfas.lib.api; + +public abstract class PdfAsParameter { + +	protected Configuration configuration; +	 +	protected IDataSource dataSource; +	 +	public PdfAsParameter(Configuration configuration,  +			IDataSource dataSource) { +		this.configuration = configuration; +		this.dataSource = dataSource; +	} + +	public Configuration getConfiguration() { +		return configuration; +	} + +	public void setConfiguration(Configuration configuration) { +		this.configuration = configuration; +	} + +	public IDataSource getDataSource() { +		return dataSource; +	} + +	public void setDataSource(IDataSource dataSource) { +		this.dataSource = dataSource; +	} +	 +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java new file mode 100644 index 00000000..debc6d4f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.api;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java new file mode 100644 index 00000000..1eee841a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java @@ -0,0 +1,37 @@ +package at.gv.egiz.pdfas.lib.api.sign; + +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IDataSource; +import at.gv.egiz.pdfas.lib.api.PdfAsParameter; + +public class SignParameter extends PdfAsParameter { + +	protected String signatureProfileId = null; +	protected String signaturePosition = null; +	 +	public SignParameter(Configuration configuration,  +			IDataSource dataSource) { +		super(configuration, dataSource); +	} + +	// ======================================================================== +	 +	public String getSignatureProfileId() { +		return signatureProfileId; +	} + +	public void setSignatureProfileId(String signatureProfileId) { +		this.signatureProfileId = signatureProfileId; +	} + +	public String getSignaturePosition() { +		return signaturePosition; +	} + +	public void setSignaturePosition(String signaturePosition) { +		this.signaturePosition = signaturePosition; +	} +	 +	 +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java new file mode 100644 index 00000000..91da083e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java @@ -0,0 +1,5 @@ +package at.gv.egiz.pdfas.lib.api.sign; + +public class SignResult { + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java new file mode 100644 index 00000000..2052ad71 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.api.sign;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java new file mode 100644 index 00000000..a021eb2a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java @@ -0,0 +1,19 @@ +package at.gv.egiz.pdfas.lib.api.verify; + +public interface SignatureCheck { +	/** +	 * Returns the response code of the check. +	 *  +	 * @return Returns the response code of the check. +	 */ +	public int getCode(); + +	/** +	 * Returns the textual response message of the check (corresponding to the +	 * code). +	 *  +	 * @return Returns the textual response message of the check (corresponding +	 *         to the code). +	 */ +	public String getMessage(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java new file mode 100644 index 00000000..8c53ad47 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java @@ -0,0 +1,14 @@ +package at.gv.egiz.pdfas.lib.api.verify; + +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IDataSource; +import at.gv.egiz.pdfas.lib.api.PdfAsParameter; + +public class VerifyParameter extends PdfAsParameter { + +	public VerifyParameter(Configuration configuration, +			IDataSource dataSource) { +		super(configuration, dataSource); +	} + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java new file mode 100644 index 00000000..339f7b15 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java @@ -0,0 +1,50 @@ +package at.gv.egiz.pdfas.lib.api.verify; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; + +public interface VerifyResult { +	/** +	 * Returns if the verification was possible or could not even be startet. +	 * see {@link #getVerificationException()} for details. +	 *  +	 * @return +	 */ +	public boolean isVerificationDone(); + +	/** +	 * Returns a verification exception if any. Shows that the verification +	 * could not be started. See {@link #isVerificationDone()}. +	 *  +	 * @return +	 */ +	public PdfAsException getVerificationException(); + +	/** +	 * Returns the result of the certificate check. +	 *  +	 * @return Returns the result of the certificate check. +	 */ +	public SignatureCheck getCertificateCheck(); + +	/** +	 * Returns the result of the value (and hash) check. +	 *  +	 * @return Returns the result of the value (and hash) check. +	 */ +	public SignatureCheck getValueCheckCode(); + +	/** +	 * Returns the result of the manifest check. +	 *  +	 * @return Returns the result of the manifest check. +	 */ +	public SignatureCheck getManifestCheckCode(); + +	/** +	 * Returns true, if the signer's certificate is a qualified certificate. +	 *  +	 * @return Returns true, if the signer's certificate is a qualified +	 *         certificate. +	 */ +	public boolean isQualifiedCertificate(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java new file mode 100644 index 00000000..68dda721 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.api.verify;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java new file mode 100644 index 00000000..d7ed5f3a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java @@ -0,0 +1,69 @@ +package at.gv.egiz.pdfas.lib.impl; + +import java.util.List; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; +import at.gv.egiz.pdfas.lib.api.PdfAs; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.api.sign.SignResult; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; +import at.gv.egiz.pdfas.lib.impl.configuration.ConfigurationImpl; +import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration; +import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; + +public class PdfAsImpl implements PdfAs, IConfigurationConstants { + +	public SignResult sign(SignParameter parameter) throws PdfAsException { +		// TODO: verify signParameter +		 +		// Status initialization +		if(!(parameter.getConfiguration() instanceof ISettings)) { +			 +		} +		ISettings settings = (ISettings) parameter.getConfiguration(); +		OperationStatus status = new OperationStatus(settings, parameter); +		PlaceholderConfiguration placeholderConfiguration = status.getPlaceholderConfiguration(); +		// set Original PDF Document Data +		status.getPdfObject().setOriginalDocument(parameter.getDataSource().getByteData()); +		 +		 +		// Placeholder search? +		if(placeholderConfiguration.isGlobalPlaceholderEnabled()) { +			// TODO: Do placeholder search +		} +		 +		RequestedSignature requestedSignature = new RequestedSignature(status); +		 +		// TODO get Certificate +		 +		if(requestedSignature.isVisual()) { +			// TODO:  SignBlockCreationStage  (visual) -> create visual signature block (logicaly) + +            // TODO:  PositioningStage (visual)  -> find position or use fixed position + +            // TODO:  StampingStage (visual) -> stamp logical signature block to location (itext) +		} else { +			// Stamped Object is equal to original +			status.getPdfObject().setStampedDocument(status.getPdfObject().getOriginalDocument()); +		} +		 +		// TODO: Create signature +		 +		return null; +	} + +	public List<VerifyResult> verify(VerifyParameter parameter) { +		// TODO Auto-generated method stub +		return null; +	} + +	public Configuration getConfiguration() { +		return new ConfigurationImpl(); +	} +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java new file mode 100644 index 00000000..b901b597 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java @@ -0,0 +1,110 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.settings.Settings; +import at.gv.egiz.pdfas.lib.api.Configuration; + +public class ConfigurationImpl implements ISettings, Configuration { + +	protected Properties overwrittenProperties = new Properties(); +	 +	public void setValue(String key, String value) { +		overwrittenProperties.setProperty(key, value); +	} + +	public String getValue(String key) { +		if(overwrittenProperties.containsKey(key)) { +			return overwrittenProperties.getProperty(key); +		} else { +			return Settings.getInstance().getValue(key); +		} +	} + +	public boolean hasValue(String key) { +		if(overwrittenProperties.containsKey(key)) { +			return true; +		} else { +			return Settings.getInstance().hasValue(key); +		} +	} + +	public Map<String, String> getValuesPrefix(String prefix) { +		 +		Map<String, String> valueMap = null; +		valueMap = Settings.getInstance().getValuesPrefix(prefix); +		if(valueMap == null) { +			valueMap = new HashMap<String, String>(); +		} +		 +		Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator(); +         +        while(keyIterator.hasNext()) { +            String key = keyIterator.next().toString(); + +            if(key.startsWith(prefix)) { +                valueMap.put(key, overwrittenProperties.getProperty(key)); +            } +        } + +        if(valueMap.isEmpty()) { +            return null; +        } + +        return valueMap; +	} + +	public Vector<String> getFirstLevelKeys(String prefix) { +		 +		Vector<String> valueMap = Settings.getInstance().getFirstLevelKeys(prefix); +		if(valueMap == null) { +			valueMap = new Vector<String>(); +		} +		 +		 +		String mPrefix = prefix.endsWith(".")?prefix:prefix+"."; +        Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator(); +         +        while(keyIterator.hasNext()) { +            String key = keyIterator.next().toString(); + +            if(key.startsWith(prefix)) { +                int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ?  key.indexOf('.', mPrefix.length()) : key.length(); +                String firstLevels = key.substring(0, keyIdx); +                if(!valueMap.contains(firstLevels)) { +                    valueMap.add(firstLevels); +                } +            } +        } + +        if(valueMap.isEmpty()) { +            return null; +        } + +        return valueMap; +	} + +	public boolean hasPrefix(String prefix) { +		 +		if(Settings.getInstance().hasPrefix(prefix)) { +			return true; +		} +		 +		Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator(); +        while(keyIterator.hasNext()) { +            String key = keyIterator.next().toString(); + +            if(key.startsWith(prefix)) { +                return true; +            } +        } +        return false; +	} + +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java new file mode 100644 index 00000000..2124f63e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java @@ -0,0 +1,21 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; + +public class GlobalConfiguration extends SpecificBaseConfiguration  +	implements IConfigurationConstants { +	 +	public GlobalConfiguration(ISettings configuration) { +		super(configuration); +	} + +	public String getDefaultSignatureProfile() { +		if(this.configuration.hasValue(DEFAULT_SIGNATURE_PROFILE)) { +			return this.configuration.getValue(DEFAULT_SIGNATURE_PROFILE); +		} +		return null; +	} +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java new file mode 100644 index 00000000..7d3beb5c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java @@ -0,0 +1,23 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; + +public class PlaceholderConfiguration extends SpecificBaseConfiguration  +		implements IConfigurationConstants { + +	public PlaceholderConfiguration(ISettings configuration) { +		super(configuration); +	} + +	public boolean isGlobalPlaceholderEnabled() { +		if(configuration.hasValue(PLACEHOLDER_SEARCH_ENABLED)) { +			String value = configuration.getValue(PLACEHOLDER_SEARCH_ENABLED); +			if(value.equalsIgnoreCase(TRUE)) { +				return true; +			} +		} +		return false; +	} +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java new file mode 100644 index 00000000..d7792dca --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java @@ -0,0 +1,21 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; + +public class SignatureProfileConfiguration extends SpecificBaseConfiguration  +	implements IConfigurationConstants { +	 +	protected String profileID; + +	public SignatureProfileConfiguration(ISettings configuration,  +			String profileID) { +		super(configuration); +		this.profileID = profileID; +	} + +	public boolean isVisualSignature() { +		String key = SIG_OBJECT + SEPERATOR + profileID + SEPERATOR + TABLE + SEPERATOR + MAIN; +		return this.configuration.hasPrefix(key); +	} +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java new file mode 100644 index 00000000..88c7b3d7 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; + +public abstract class SpecificBaseConfiguration { +	 +	protected ISettings configuration; + +	public SpecificBaseConfiguration(ISettings configuration) { +		this.configuration = configuration; +	} +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java new file mode 100644 index 00000000..d766824e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.configuration;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java new file mode 100644 index 00000000..aba811aa --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java new file mode 100644 index 00000000..340ba0bb --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java @@ -0,0 +1,251 @@ +package at.gv.egiz.pdfas.lib.impl.positioning; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; +import at.gv.egiz.pdfas.common.utils.PDFUtils; +import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/29/13 + * Time: 4:30 PM + * To change this template use File | Settings | File Templates. + */ +public class Positioning { + +    /** +     * The left/right margin. +     */ +    public static final float SIGNATURE_MARGIN_HORIZONTAL = 50f; + +    /** +     * The top/bottom margin. +     */ +    public static final float SIGNATURE_MARGIN_VERTICAL = 20f; + +    /** +     * Evalutates absolute positioning and prepares the PositioningInstruction for +     * placing the table. +     * +     * @param pos +     *          The absolute positioning parameter. If null it is sought in the +     *          profile definition. +     * @param signature_type +     *          The profile definition of the table to be written. +     * @param pdfDataSource +     *          The pdf. +     * @param pdf_table +     *          The pdf table to be written. +     * @return Returns the PositioningInformation. +     * @throws PdfAsException +     *           F.e. +     */ +    public static PositioningInstruction determineTablePositioning(TablePos pos, String signature_type, +            PDDocument pdfDataSource, IPDFVisualObject pdf_table) throws PdfAsException +    { +        boolean legacy32 = false; + +        //TODO: settings reader ... + +        /* +        if (pos == null) +        { +            String pos_string = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".pos", null); +            if (pos_string != null) +            { +                pos = PdfAS.parsePositionFromPosString(pos_string); +            } +        } +        if (pos == null) +        { +            // The default algorithm. x,y,w =auto ,p=lastpage, f:ignored because +            // y:auto +            pos = new TablePos(); +        } + +        // afitzek +        // Allow legacy positioning (3.2) for BRZ Templates ... +        boolean legacy32 = false; +        String leg = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".legacy.pos", "false"); +        if (leg != null) { +            if ("true".equals(leg.trim())) { +                legacy32 = true; +            } +        } +        */ +        // System.out.println("Tablepos="+pos); +        return adjustSignatureTableandCalculatePosition(pdfDataSource, pdf_table, pos, legacy32); +    } + +    /** +     * Sets the width of the table according to the layout of the document and +     * calculates the y position where the PDFPTable should be placed. +     * +     * @param pdfDataSource +     *          The PDF document. +     * @param pdf_table +     *          The PDFPTable to be placed. +     * @return Returns the position where the PDFPTable should be placed. +     * @throws PdfAsException +     *           F.e. +     */ +    public static PositioningInstruction adjustSignatureTableandCalculatePosition(final PDDocument pdfDataSource, +        IPDFVisualObject pdf_table, TablePos pos, boolean legacy32) throws PdfAsException +    { + +        try { +            PDFUtils.checkPDFPermissions(pdfDataSource); +            // get pages of currentdocument + +            int doc_pages = pdfDataSource.getNumberOfPages(); +            int page = doc_pages; +            boolean make_new_page = pos.isNewPage(); +            if (!(pos.isNewPage() || pos.isPauto())) +            { +                // we should posit signaturtable on this page + +                page = pos.getPage(); +                // System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages); +                if (page > doc_pages) +                { +                    make_new_page = true; +                    page = doc_pages; +                    // throw new PDFDocumentException(227, "Page number is to big(=" + page+ +                    // ") cannot be parsed."); +                } +            } + +            PDPage pdPage = (PDPage)pdfDataSource.getDocumentCatalog().getAllPages().get(page - 1); +            PDRectangle cropBox = pdPage.getCropBox(); + +            if(cropBox == null) { +                cropBox = pdPage.findCropBox(); +            } + + +            if(cropBox == null) { +                cropBox = pdPage.findMediaBox(); +            } + +            //TODO: fallback to MediaBox if Cropbox not available! + +            // getPagedimensions +            //Rectangle psize = reader.getPageSizeWithRotation(page); +            //int page_rotation = reader.getPageRotation(page); + +            //Integer rotation = pdPage.getRotation(); +            //int page_rotation = rotation.intValue(); + +            float page_width = cropBox.getWidth(); +            float page_height = cropBox.getHeight(); + +            // now we can calculate x-position +            float pre_pos_x = SIGNATURE_MARGIN_HORIZONTAL; +            if (!pos.isXauto()) +            { +                // we do have absolute x +                pre_pos_x = pos.getPosX(); +            } +            // calculate width +            // center +            float pre_width = page_width - 2*pre_pos_x; +            if (!pos.isWauto()) +            { +                // we do have absolute width +                pre_width = pos.getWidth(); +                if (pos.isXauto()) +                { // center x +                    pre_pos_x = (page_width - pre_width) / 2; +                } +            } +            final float pos_x = pre_pos_x; +            final float width = pre_width; +            // Signatur table dimensions are complete +            pdf_table.setWidth(width); +            pdf_table.fixWidth(); +            //pdf_table.setTotalWidth(width); +            //pdf_table.setLockedWidth(true); + +            final float table_height = pdf_table.getHeight(); +            // now check pos_y +            float pos_y = pos.getPosY(); + +            // in case an absolute y position is already given OR +            // if the table is related to an invisible signature +            // there is no need for further calculations +            // (fixed adding new page in case of invisible signatures) +            if (!pos.isYauto() || table_height == 0) +            { +                // we do have y-position too --> all parameters but page ok +                if (make_new_page) +                { +                    page++; +                } +                return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +            } +            // pos_y is auto +            if (make_new_page) +            { +                // ignore footer in new page +                page++; +                pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; +                return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +            } +            // up to here no checks have to be made if Tablesize and Pagesize are fit +            // Now we have to getfreespace in page and reguard footerline +            float footer_line = pos.getFooterLine(); +            float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource, page - 1, page_height - footer_line, /*page_rotation,*/ legacy32); +            if (pre_page_length == Float.NEGATIVE_INFINITY) +            { +                // we do have an empty page or nothing in area above footerline +                pre_page_length = page_height; +                // no text --> SIGNATURE_BORDER +                pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; +                if (pos_y - footer_line <= table_height) +                { +                    make_new_page = true; +                    if (!pos.isPauto()) +                    { +                        // we have to correct pagenumber +                        page = pdfDataSource.getNumberOfPages(); +                    } +                    page++; +                    // no text --> SIGNATURE_BORDER +                    pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; +                } +                return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +            } +            final float page_length = pre_page_length; +            // we do have text take SIGNATURE_MARGIN +            pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL; +            if (pos_y - footer_line <= table_height) +            { +                make_new_page = true; +                if (!pos.isPauto()) +                { +                    // we have to correct pagenumber in case of absolute page and not enough +                    // space +                    page = pdfDataSource.getNumberOfPages(); +                } +                page++; +                // no text --> SIGNATURE_BORDER +                pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; +            } +            return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +        } finally { +            if (pdfDataSource != null) { +                try { +                    pdfDataSource.close(); +                } catch (Exception e) { +                } +            } +        } +    } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java new file mode 100644 index 00000000..5b209e06 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.positioning;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java new file mode 100644 index 00000000..f1b59ceb --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java @@ -0,0 +1,12 @@ +package at.gv.egiz.pdfas.lib.impl.stamping; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.impl.status.PDFObject; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.table.Table; + +public interface IPDFStamper { +    public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table); +    public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction, +                                    byte[] pdfData) throws PdfAsException; +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java new file mode 100644 index 00000000..fd7cac5c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java @@ -0,0 +1,12 @@ +package at.gv.egiz.pdfas.lib.impl.stamping; + +public interface IPDFVisualObject { +    public void setWidth(float width); +    public void fixWidth(); +    public float getHeight(); +    public float getWidth(); +    public void setXPos(float x); +    public void setYPos(float x); +    public int getPage(); +    public void setPage(int page); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java new file mode 100644 index 00000000..1720057a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java @@ -0,0 +1,18 @@ +package at.gv.egiz.pdfas.lib.impl.stamping; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; + +public class StamperFactory { + +	public static final String DEFAULT_STAMPER_CLASS = "at.gv.egiz.pdfas.stmp.itext.ITextStamper"; + +	public static IPDFStamper createDefaultStamper() throws PdfAsException { +		try { +			Class<? extends IPDFStamper> cls = (Class<? extends IPDFStamper>)  +					Class.forName(DEFAULT_STAMPER_CLASS); +			return cls.newInstance(); +		} catch (Throwable e) { +			throw new PdfAsException("NO STAMPER!", e); +		} +	} +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java new file mode 100644 index 00000000..496f592f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.stamping;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java new file mode 100644 index 00000000..d7b956a7 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java @@ -0,0 +1,76 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +import java.util.HashMap; +import java.util.Map; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.configuration.GlobalConfiguration; +import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration; +import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; + +public class OperationStatus { +	 +	private SignParameter signParamter; +	private PDFObject pdfObject = new PDFObject(); +	 +	 +	private ISettings configuration; +	private PlaceholderConfiguration placeholderConfiguration = null; +	private GlobalConfiguration gloablConfiguration = null; +	private Map<String, SignatureProfileConfiguration> signatureProfiles =  +				new HashMap<String, SignatureProfileConfiguration>(); +	 +	public OperationStatus(ISettings configuration, SignParameter signParameter) { +		this.configuration = configuration; +		this.signParamter = signParameter; +	} +	 +	// ======================================================================== +	 +	public PlaceholderConfiguration getPlaceholderConfiguration() { +		if(this.placeholderConfiguration == null) { +			this.placeholderConfiguration =  +					new PlaceholderConfiguration(this.configuration); +		} +		return this.placeholderConfiguration; +	} +	 +	public GlobalConfiguration getGlobalConfiguration() { +		if(this.gloablConfiguration == null) { +			this.gloablConfiguration =  +					new GlobalConfiguration(this.configuration); +		} +		return this.gloablConfiguration; +	} +	 +	public SignatureProfileConfiguration getSignatureProfileConfiguration(String profileID) { +		 +		SignatureProfileConfiguration signatureProfileConfiguration = signatureProfiles.get(profileID); +		if(signatureProfileConfiguration == null) { +			signatureProfileConfiguration = new SignatureProfileConfiguration(this.configuration, profileID); +			signatureProfiles.put(profileID, signatureProfileConfiguration); +		} +		 +		return signatureProfileConfiguration; +	} +	 +	// ======================================================================== +	 +	public PDFObject getPdfObject() { +		return pdfObject; +	} + +	public void setPdfObject(PDFObject pdfObject) { +		this.pdfObject = pdfObject; +	} + +	public SignParameter getSignParamter() { +		return signParamter; +	} + +	public void setSignParamter(SignParameter signParamter) { +		this.signParamter = signParamter; +	} +	 +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java new file mode 100644 index 00000000..1fe64bee --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java @@ -0,0 +1,31 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +public class PDFObject { +	private byte[] originalDocument; +	private byte[] stampedDocument; +	private byte[] signedDocument; + +	public byte[] getOriginalDocument() { +		return originalDocument; +	} + +	public void setOriginalDocument(byte[] originalDocument) { +		this.originalDocument = originalDocument; +	} + +	public byte[] getStampedDocument() { +		return stampedDocument; +	} + +	public void setStampedDocument(byte[] stampedDocument) { +		this.stampedDocument = stampedDocument; +	} + +	public byte[] getSignedDocument() { +		return signedDocument; +	} + +	public void setSignedDocument(byte[] signedDocument) { +		this.signedDocument = signedDocument; +	} +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java new file mode 100644 index 00000000..a78828f3 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java @@ -0,0 +1,53 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; + + +public class RequestedSignature { +    private String signatureProfile; +    private TablePos signaturePosition; +    private OperationStatus status; +    //private IPlainSigner signer = null; + +    public RequestedSignature(OperationStatus status) throws PdfAsException { +    	 +    	this.status = status; +    	 +    	String profileID = status.getSignParamter().getSignatureProfileId(); +    	 +    	if(profileID == null) { +    		profileID = status.getGlobalConfiguration().getDefaultSignatureProfile(); +    		 +    		if(profileID == null) { +    			throw new PdfAsSettingsException("Failed to determine Signature Profile!"); +    		} +    	} +    	 +    	this.signatureProfile = profileID; +    	 +    	if(status.getSignParamter().getSignaturePosition() == null) { +    		this.signaturePosition = new TablePos(); +    	} else { +    		this.signaturePosition = new TablePos(status.getSignParamter().getSignaturePosition()); +    	} +    } +     +    public boolean isVisual() { +        return this.status.getSignatureProfileConfiguration(signatureProfile).isVisualSignature(); +    } +     +    public TablePos getTablePos() { +    	return this.signaturePosition; +    } + +/* +    public IPlainSigner getSigner() { +        return signer; +    } + +    public void setSigner(IPlainSigner signer) { +        this.signer = signer; +    }*/ +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java new file mode 100644 index 00000000..4321a9b5 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java @@ -0,0 +1 @@ +package at.gv.egiz.pdfas.lib.impl.status;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java new file mode 100644 index 00000000..62eb0d25 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java @@ -0,0 +1,4 @@ +/** + *  + */ +package at.gv.egiz.pdfas.lib;
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java new file mode 100644 index 00000000..b5928406 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java @@ -0,0 +1,502 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: PDFPage.java,v 1.5 2006/10/31 08:09:33 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.pdf;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.*;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.*;
 +
 +import org.apache.commons.lang3.math.NumberUtils;
 +import org.apache.pdfbox.cos.COSName;
 +import org.apache.pdfbox.cos.COSStream;
 +import org.apache.pdfbox.pdmodel.PDPage;
 +import org.apache.pdfbox.pdmodel.PDResources;
 +import org.apache.pdfbox.pdmodel.common.PDRectangle;
 +import org.apache.pdfbox.pdmodel.common.PDStream;
 +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
 +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
 +import org.apache.pdfbox.util.Matrix;
 +import org.apache.pdfbox.util.PDFOperator;
 +import org.apache.pdfbox.util.PDFTextStripper;
 +import org.apache.pdfbox.util.TextPosition;
 +import org.apache.pdfbox.util.operator.OperatorProcessor;
 +import org.slf4j.Logger;
 +import org.slf4j.LoggerFactory;
 +
 +import java.awt.*;
 +import java.awt.geom.GeneralPath;
 +import java.io.IOException;
 +import java.io.Writer;
 +import java.util.List;
 +import java.util.Map;
 +
 +/**
 + * PDFPage is an inner class that is used to calculate the page length of a PDF
 + * Document page. It extends the PDFTextStripper class and implement one
 + * interested method: {@link at.knowcenter.wag.egov.egiz.pdf.PDFPage#showCharacter(TextPosition)}<br>
 + * This method is called when processing the FileStream. By calling the method
 + * {@link org.apache.pdfbox.util.PDFStreamEngine#processStream(org.apache.pdfbox.pdmodel.PDPage, org.apache.pdfbox.pdmodel.PDResources, org.pdfbox.cos.COSStream)}
 + * the implemented method showCharacter is called.
 + * 
 + * @author wlackner
 + * @see PDFTextStripper
 + */
 +public class PDFPage extends PDFTextStripper {
 +	/**
 +	 * The logger definition.
 +	 */
 +    private static final Logger logger = LoggerFactory.getLogger(PDFPage.class);
 +
 +	/**
 +	 * The maximum (lowest) y position of a character.
 +	 */
 +	protected float max_character_ypos = Float.NEGATIVE_INFINITY;
 +
 +	/**
 +	 * The maximum (lowest y position of an image.
 +	 */
 +	protected float max_image_ypos = Float.NEGATIVE_INFINITY;
 +
 +	/**
 +	 * The effective page height.
 +	 */
 +	protected float effectivePageHeight;
 +
 +	/**
 +	 * The path currently being constructed.
 +	 */
 +	private GeneralPath currentPath = new GeneralPath();
 +
 +	/**
 +	 * The lowest position of a drawn path (originating from top).
 +	 */
 +	private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY;
 +
 +	/**
 +	 * Constructor.
 +	 * 
 +	 * @param effectivePageHeight
 +	 *            The height of the page to be evaluated. PDF elements outside
 +	 *            this height will not be considered.
 +	 * 
 +	 * @throws java.io.IOException
 +	 */
 +	public PDFPage(float effectivePageHeight, boolean legacy32) throws IOException {
 +		super();
 +
 +		this.effectivePageHeight = effectivePageHeight;
 +
 +		OperatorProcessor newInvoke = new MyInvoke(this);
 +		newInvoke.setContext(this);
 +        this.registerOperatorProcessor("Do", newInvoke);
 +        
 +		if (!legacy32) {
 +			registerCustomPathOperators();
 +		}
 +	}
 +
 +	/**
 +	 * Registers operators responsible for path construction and painting in
 +	 * order to fix auto positioning on pages with path elements.
 +	 * 
 +	 * @author Datentechnik Innovation GmbH
 +	 */
 +	@SuppressWarnings("unchecked")
 +	private void registerCustomPathOperators() {
 +
 +		// *** path construction
 +
 +        this.registerOperatorProcessor("m", new MoveTo(this));
 +        this.registerOperatorProcessor("l", new LineTo(this));
 +        this.registerOperatorProcessor("c", new CurveTo(this));
 +        this.registerOperatorProcessor("y", new CurveToReplicateFinalPoint(this));
 +        this.registerOperatorProcessor("v", new CurveToReplicateInitialPoint(this));
 +        this.registerOperatorProcessor("h", new ClosePath(this));
 +
 +		// *** path painting
 +
 +		// "S": stroke path
 +        this.registerOperatorProcessor("S", new StrokePath(this));
 +        this.registerOperatorProcessor("s", new CloseAndStrokePath(this));
 +        this.registerOperatorProcessor("f", new FillPathNonZeroWindingNumberRule(this));
 +        this.registerOperatorProcessor("F", new FillPathNonZeroWindingNumberRule(this));
 +        this.registerOperatorProcessor("f*", new FillPathEvenOddRule(this));
 +        this.registerOperatorProcessor("b", new CloseFillNonZeroAndStrokePath(this));
 +        this.registerOperatorProcessor("B", new FillNonZeroAndStrokePath(this));
 +        this.registerOperatorProcessor("b*", new CloseFillEvenOddAndStrokePath(this));
 +        this.registerOperatorProcessor("B*", new FillEvenOddAndStrokePath(this));
 +        this.registerOperatorProcessor("n", new EndPath(this));
 +
 +		// Note: The graphic context
 +		// (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying
 +		// pdfbox library does
 +		// not yet support clipping. This prevents feasible usage of clipping
 +		// operators (W, W*).
 +		// operators.put("W", new ...(this));
 +		// operators.put("W*", new ...(this));
 +
 +	}
 +
 +	/**
 +	 * Returns the path currently being constructed.
 +	 * 
 +	 * @return The path currently being constructed.
 +	 */
 +	public GeneralPath getCurrentPath() {
 +		return currentPath;
 +	}
 +
 +	/**
 +	 * Sets the current path.
 +	 * 
 +	 * @param currentPath
 +	 *            The new current path.
 +	 */
 +	public void setCurrentPath(GeneralPath currentPath) {
 +		this.currentPath = currentPath;
 +	}
 +
 +	/**
 +	 * Registers a rectangle that bounds the path currently being drawn.
 +	 * 
 +	 * @param bounds
 +	 *            A rectangle depicting the bounds (coordinates originating from
 +	 *            bottom left).
 +	 * @author Datentechnik Innovation GmbH
 +	 */
 +	public void registerPathBounds(Rectangle bounds) {
 +		if (!bounds.isEmpty()) {
 +			logger.debug("Registering path bounds: " + bounds);
 +
 +			// vertical start of rectangle (counting from top of page)
 +			float upperBoundYPositionFromTop;
 +
 +			// vertical end of rectangle (counting from top of page)
 +			// this depicts the current end of path-related page content
 +			float lowerBoundYPositionFromTop;
 +
 +			PDRectangle boundaryBox = this.getCurrentPage().findMediaBox();
 +			float pageHeight;
 +
 +			switch (this.getCurrentPage().findRotation()) {
 +			case 90: // CW
 +				pageHeight = boundaryBox.getWidth();
 +				upperBoundYPositionFromTop = (float) bounds.getMinX();
 +				lowerBoundYPositionFromTop = (float) bounds.getMaxX();
 +				break;
 +			case 180:
 +				pageHeight = boundaryBox.getHeight();
 +				upperBoundYPositionFromTop = (float) bounds.getMinY();
 +				lowerBoundYPositionFromTop = (float) bounds.getMaxY();
 +				break;
 +			case 270: // CCW
 +				pageHeight = boundaryBox.getWidth();
 +				upperBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMaxX();
 +				lowerBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMinX();
 +				break;
 +			default:
 +				pageHeight = boundaryBox.getHeight();
 +				upperBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMaxY();
 +				lowerBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMinY();
 +				break;
 +			}
 +
 +			// new maximum ?
 +			if (lowerBoundYPositionFromTop > maxPathRelatedYPositionFromTop) {
 +				// Is the rectangle (at least partly) located above the footer
 +				// line?
 +				// (effective page height := page height - footer line)
 +				if (upperBoundYPositionFromTop <= effectivePageHeight) {
 +					// yes: update current end of path-related page content
 +					maxPathRelatedYPositionFromTop = lowerBoundYPositionFromTop;
 +					logger.trace("New max path related y position (from top): "
 +							+ maxPathRelatedYPositionFromTop);
 +				} else {
 +					// no: rectangle is fully located below the footer line ->
 +					// ignore
 +					logger.trace("Ignoring path bound below the footer line.");
 +				}
 +			}
 +		}
 +	}
 +
 +	protected void processOperator(PDFOperator operator, List arguments)
 +			throws IOException {
 +		logger.trace("operator = " + operator);
 +		super.processOperator(operator, arguments);
 +	}
 +
 +	@Override
 +	protected void processTextPosition(TextPosition text) {
 +		showCharacter(text);
 +	}
 +	
 +	// exthex
 +	/**
 +	 * A method provided as an event interface to allow a subclass to perform
 +	 * some specific functionality when a character needs to be displayed. This
 +	 * method is used to calculate the latest position of a text in the page.
 +	 * Sorry for this missinterpretation of the method, but it is the only way
 +	 * to do this (provided by PDFBox)!!!
 +	 * 
 +	 * @param text
 +	 *            the character to be displayed -> calculate there y position.
 +	 */
 +	protected void showCharacter(TextPosition text) {
 +		float current_y = text.getY();
 +		final String character = text.getCharacter();
 +
 +		int pageRotation = this.getCurrentPage().findRotation();
 +		// logger_.debug("PageRotation = " + pageRotation);
 +		if (pageRotation == 0) {
 +			current_y = text.getY();
 +		}
 +		if (pageRotation == 90) {
 +			current_y = text.getX();
 +		}
 +		if (pageRotation == 180) {
 +			float page_height = this.getCurrentPage().findMediaBox().getHeight();
 +			current_y = page_height - text.getY();
 +		}
 +		if (pageRotation == 270) {
 +			float page_height = this.getCurrentPage().findMediaBox().getHeight();
 +			current_y = page_height - text.getX();
 +		}
 +
 +		if (current_y > this.effectivePageHeight) {
 +			// logger_.debug("character is below footer_line. footer_line = " +
 +			// this.footer_line + ", text.character=" + character + ", y=" +
 +			// current_y);
 +			return;
 +		}
 +
 +		// store ypos of the char if it is not empty
 +		if (!character.equals(" ") && current_y > this.max_character_ypos) {
 +			this.max_character_ypos = current_y;
 +		}
 +
 +	}
 +
 +	// use this funtion getting an unsorted text output
 +	// public void showString(byte[] string) {
 +	// logger_.debug(new String(string));
 +	// }
 +
 +	/**
 +	 * Returns the calculated page length.
 +	 * 
 +	 * @return the max page length value
 +	 */
 +	public float getMaxPageLength() {
 +		if (logger.isDebugEnabled()) {
 +			logger.debug("Determining page content length: text="
 +					+ max_character_ypos + ", image=" + max_image_ypos
 +					+ ", path=" + maxPathRelatedYPositionFromTop);
 +		}
 +		return NumberUtils.max(max_character_ypos, max_image_ypos,
 +                maxPathRelatedYPositionFromTop);
 +	}
 +
 +	public class MyInvoke extends OperatorProcessor {
 +
 +        private PDFPage mypage;
 +
 +        public MyInvoke(PDFPage page) {
 +            this.mypage = page;
 +        }
 +
 +		public void process(PDFOperator operator, List arguments)
 +				throws IOException {
 +			COSName name = (COSName) arguments.get(0);
 +
 +			// PDResources res = context.getResources();
 +
 +			Map xobjects = context.getXObjects();
 +			PDXObject xobject = (PDXObject) xobjects.get(name.getName());
 +
 +			PDStream stream = xobject.getPDStream();
 +			COSStream cos_stream = stream.getStream();
 +
 +			COSName subtype = (COSName) cos_stream
 +					.getDictionaryObject(COSName.SUBTYPE);
 +			if (subtype.equals(COSName.IMAGE)) {
 +				logger.debug("XObject Image");
 +
 +				Matrix ctm = context.getGraphicsState()
 +						.getCurrentTransformationMatrix();
 +                logger.debug("ctm = " + ctm);
 +
 +				Pos[] coordinates = new Pos[] { new Pos(0, 0, 1),
 +						new Pos(1, 0, 1), new Pos(0, 1, 1), new Pos(1, 1, 1) };
 +
 +				Pos[] transformed_coordinates = transtormCoordinates(
 +						coordinates, ctm);
 +
 +				/**********************************************************
 +				 * pdf-as fix: calculating min and max point of an image to look
 +				 * where the signature should be placed fix solves problems with
 +				 * footer and images and placement of the signature in an image
 +				 * only pdf document
 +				 **********************************************************/
 +
 +				float actual_lowest_point = Float.NaN;
 +				float actual_starting_point = Float.NaN;
 +
 +				int pageRotation = this.mypage.getCurrentPage().findRotation();
 +				logger.debug("PageRotation = " + pageRotation);
 +				if (pageRotation == 0) {
 +					float min_y = findMinY(transformed_coordinates);
 +                    logger.debug("min_y = " + min_y);
 +					float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight();
 +                    logger.debug("page_height = " + page_height);
 +
 +					actual_lowest_point = page_height - min_y;
 +					actual_starting_point = page_height
 +							- findMaxY(transformed_coordinates);
 +				}
 +				if (pageRotation == 90) {
 +					float max_x = findMaxX(transformed_coordinates);
 +                    logger.debug("max_x = " + max_x);
 +					float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth();
 +                    logger.debug("page_width = " + page_width);
 +
 +					actual_lowest_point = max_x;
 +					actual_starting_point = findMinX(transformed_coordinates);
 +				}
 +				if (pageRotation == 180) {
 +					float min_y = findMinY(transformed_coordinates);
 +                    logger.debug("min_y = " + min_y);
 +					float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight();
 +					actual_lowest_point = page_height
 +							- findMaxY(transformed_coordinates);
 +					actual_starting_point = page_height - min_y;
 +				}
 +				if (pageRotation == 270) {
 +					float min_x = findMinX(transformed_coordinates);
 +                    logger.debug("min_x = " + min_x);
 +
 +					float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth();
 +                    logger.debug("page_width = " + page_width);
 +
 +					actual_lowest_point = page_width - min_x;
 +					actual_starting_point = page_width
 +							- findMaxX(transformed_coordinates);
 +				}
 +
 +                logger.debug("actual_lowest_point = " + actual_lowest_point);
 +
 +				if (actual_lowest_point > PDFPage.this.effectivePageHeight
 +						&& actual_starting_point > PDFPage.this.effectivePageHeight) {
 +                    logger.debug("image is below footer_line");
 +					return;
 +				}
 +
 +				if (actual_lowest_point > PDFPage.this.max_image_ypos) {
 +					PDFPage.this.max_image_ypos = actual_lowest_point;
 +				}
 +
 +				return;
 +			}
 +
 +			if (xobject instanceof PDXObjectForm) {
 +				PDXObjectForm form = (PDXObjectForm) xobject;
 +				COSStream invoke = (COSStream) form.getCOSObject();
 +				PDResources pdResources = form.getResources();
 +				PDPage page = context.getCurrentPage();
 +				if (pdResources == null) {
 +					pdResources = page.findResources();
 +				}
 +
 +				getContext().processSubStream(page, pdResources, invoke);
 +			}
 +		}
 +	}
 +
 +	public static Pos[] transtormCoordinates(Pos[] coordinates, Matrix m) {
 +		Pos[] transformed = new Pos[coordinates.length];
 +		for (int i = 0; i < coordinates.length; i++) {
 +			transformed[i] = transtormCoordinate(coordinates[i], m);
 +		}
 +		return transformed;
 +	}
 +
 +	public static Pos transtormCoordinate(Pos pos, Matrix m) {
 +		Pos transformed = new Pos();
 +		transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0)
 +				+ pos.z * m.getValue(2, 0);
 +		transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1)
 +				+ pos.z * m.getValue(2, 1);
 +		transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2)
 +				+ pos.z * m.getValue(2, 2);
 +
 +        logger.debug(" transformed " + pos + " --> " + transformed);
 +		return transformed;
 +	}
 +
 +	public static float findMinY(Pos[] coordinates) {
 +		float min = Float.POSITIVE_INFINITY;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].y < min) {
 +				min = coordinates[i].y;
 +			}
 +		}
 +		return min;
 +	}
 +
 +	public static float findMaxY(Pos[] coordinates) {
 +		float max = 0;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].y > max) {
 +				max = coordinates[i].y;
 +			}
 +		}
 +		return max;
 +	}
 +
 +	public static float findMaxX(Pos[] coordinates) {
 +		float max = Float.NEGATIVE_INFINITY;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].x > max) {
 +				max = coordinates[i].x;
 +			}
 +		}
 +		return max;
 +	}
 +
 +	public static float findMinX(Pos[] coordinates) {
 +		float min = Float.POSITIVE_INFINITY;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].x < min) {
 +				min = coordinates[i].x;
 +			}
 +		}
 +		return min;
 +	}
 +
 +}
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java new file mode 100644 index 00000000..7f223b40 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java @@ -0,0 +1,72 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: PDFUtilities.java,v 1.3 2006/10/31 08:09:33 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.pdf;
 +
 +import java.io.IOException;
 +import java.util.List;
 +
 +import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
 +import org.apache.pdfbox.cos.COSStream;
 +import org.apache.pdfbox.pdmodel.PDDocument;
 +import org.apache.pdfbox.pdmodel.PDPage;
 +import org.apache.pdfbox.pdmodel.PDResources;
 +import org.apache.pdfbox.pdmodel.interactive.pagenavigation.PDThreadBead;
 +
 +
 +/**
 + * Contains useful helpers for accessing PDF documents.
 + *
 + * @author wprinz
 + * @author mruhmer
 + */
 +public abstract class PDFUtilities
 +{
 +    public static float calculatePageLength(PDDocument document, int page, float effectivePageHeight, /*int pagerotation,*/ boolean legacy32) throws PDFIOException {
 +	    //int last_page_id = document.getNumberOfPages();
 +	    List allPages = document.getDocumentCatalog().getAllPages();
 +	    PDPage pdpage = (PDPage) allPages.get(page);
 +	    //pdpage.setRotation(pagerotation);
 +	    return calculatePageLength(pdpage, effectivePageHeight, legacy32);
 +	}
 +
 +    public static float calculatePageLength(PDPage page, float effectivePageHeight, boolean legacy32) throws PDFIOException
 +    {
 +        try{
 +            PDFPage my_page = new PDFPage(effectivePageHeight, legacy32);
 +            PDResources resources = page.findResources();
 +            COSStream stream = page.getContents().getStream();
 +            //List<PDThreadBead> articles = page.getThreadBeads();
 +            //my_page.processMyPage(page);
 +            my_page.processStream(page, resources, stream);
 +            return my_page.getMaxPageLength();
 +        }
 +        catch (IOException e)
 +        {
 +            throw new PDFIOException("calculatePageLength", e);
 +        }
 +    }
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java new file mode 100644 index 00000000..6f03fed4 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java @@ -0,0 +1,70 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: Pos.java,v 1.1 2006/08/25 17:10:08 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.pdf;
 +
 +/**
 + * Encapsulation of a position on a PDF page.
 + * 
 + * @author wprinz
 + */
 +public class Pos
 +{
 +
 +  public float x;
 +
 +  public float y;
 +
 +  public float z;
 +
 +  /**
 +   * Default constructor.
 +   */
 +  public Pos()
 +  {
 +  }
 +
 +  /**
 +   * Constructor that sets the coordinates.
 +   * @param xx
 +   * @param yy
 +   * @param zz
 +   */
 +  public Pos(float xx, float yy, float zz)
 +  {
 +    this.x = xx;
 +    this.y = yy;
 +    this.z = zz;
 +  }
 +
 +  /**
 +   * @see Object#toString()
 +   */
 +  public String toString()
 +  {
 +    return "(" + this.x + "," + this.y + "," + this.z + ")";
 +  }
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java new file mode 100644 index 00000000..0fe399c4 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java @@ -0,0 +1,182 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id:  $
 + */
 +package at.knowcenter.wag.egov.egiz.pdf;
 +
 +/**
 + * The positioning instruction holds information of where to place the signature
 + * block.
 + * 
 + * <p>
 + * This instruction is given to the PDF writer in order to place the signature.
 + * </p>
 + * 
 + * @author wprinz
 + */
 +public class PositioningInstruction
 +{
 +
 +  /**
 +   * Tells, if a new plain page should be appended.
 +   * 
 +   * <p>
 +   * This command is executed before the signature block is positioned according
 +   * to page, x and y.
 +   * </p>
 +   */
 +  protected boolean make_new_page = false;
 +
 +  /**
 +   * The number of the page on which the signature block is to be placed. If
 +   * specified to make a new page, the number of this newly created page can be
 +   * used here as well.
 +   */
 +  protected int page = 0;
 +
 +  /**
 +   * The x coordinate where the upper left corner of the signature block should
 +   * be placed.
 +   */
 +  protected float x = 0.0f;
 +
 +  /**
 +   * The y coordinate where the upper left corner of the signature block should
 +   * be placed.
 +   */
 +  protected float y = 0.0f;
 +
 +  /**
 +   * 
 +   * @param make_new_page
 +   *          Tells, if a new plain page should be appended. This command is
 +   *          executed before the signature block is positioned according to
 +   *          page, x and y.
 +   * @param page
 +   *          The number of the page on which the signature block is to be
 +   *          placed. If specified to make a new page, the number of this newly
 +   *          created page can be used here as well.
 +   * @param x
 +   *          The x coordinate where the upper left corner of the signature
 +   *          block should be placed.
 +   * @param y
 +   *          The y coordinate where the upper left corner of the signature
 +   *          block should be placed.
 +   */
 +  public PositioningInstruction(boolean make_new_page, int page, float x, float y)
 +  {
 +    this.make_new_page = make_new_page;
 +    this.page = page;
 +    this.x = x;
 +    this.y = y;
 +  }
 +
 +  /**
 +   * Tells, if a new plain page should be appended to the document.
 +   * 
 +   * @return Returns true, if a new plain page should be appended.
 +   */
 +  public boolean isMakeNewPage()
 +  {
 +    return this.make_new_page;
 +  }
 +
 +  /**
 +   * Returns the page on which the signature is to be printed.
 +   * 
 +   * @return Returns the page on which the signature is to be printed.
 +   */
 +  public int getPage()
 +  {
 +    return this.page;
 +  }
 +
 +  /**
 +   * Returns the x coordinate where the upper left corner of the signature block
 +   * should be placed.
 +   * 
 +   * @return Returns the x coordinate where the upper left corner of the
 +   *         signature block should be placed.
 +   */
 +  public float getX()
 +  {
 +    return this.x;
 +  }
 +
 +  /**
 +   * Returns the y coordinate where the upper left corner of the signature block
 +   * should be placed.
 +   * 
 +   * @return Returns the y coordinate where the upper left corner of the
 +   *         signature block should be placed.
 +   */
 +  public float getY()
 +  {
 +    return this.y;
 +  }
 +
 +	public int hashCode() {
 +		final int prime = 31;
 +		int result = 1;
 +		result = prime * result + (make_new_page ? 1231 : 1237);
 +		result = prime * result + page;
 +		result = prime * result + Float.floatToIntBits(x);
 +		result = prime * result + Float.floatToIntBits(y);
 +		return result;
 +	}
 +
 +	public boolean equals(Object obj) {
 +		if (this == obj)
 +			return true;
 +		if (obj == null)
 +			return false;
 +		if (!(obj instanceof PositioningInstruction))
 +			return false;
 +		PositioningInstruction other = (PositioningInstruction) obj;
 +		if (make_new_page != other.make_new_page)
 +			return false;
 +		if (page != other.page)
 +			return false;
 +		if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
 +			return false;
 +		if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
 +			return false;
 +		return true;
 +	}
 +
 +	public String toString() {
 +		StringBuffer buffer = new StringBuffer();
 +		buffer.append("PositioningInstruction [page=");
 +		buffer.append(page);
 +		buffer.append(", make_new_page=");
 +		buffer.append(make_new_page);
 +		buffer.append(", x=");
 +		buffer.append(x);
 +		buffer.append(", y=");
 +		buffer.append(y);
 +		buffer.append("]");
 +		return buffer.toString();
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java new file mode 100644 index 00000000..92afaf98 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java @@ -0,0 +1,261 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: TablePos.java,v 1.1 2006/08/25 17:10:08 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.pdf;
 +
 +import java.io.Serializable;
 +
 +import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
 +
 +/**
 + * Class that holds the exact position where the table should be written to the
 + * document.
 + * 
 + * @author wprinz
 + * @author mruhmer
 + */
 +public class TablePos implements Serializable
 +{
 +
 +  /**
 +   * SVUID.
 +   */
 +  private static final long serialVersionUID = -5299027706623518059L;
 +
 +  /**
 +   * The page on which the block should be displayed.
 +   * 
 +   */
 +  private int page = 0;
 +
 +  /**
 +   * The x position.
 +   */
 +  private float pos_x = 0.0f;
 +
 +  /**
 +   * The y position.
 +   */
 +  private float pos_y = 0.0f;
 +
 +  /**
 +   * The width of the block.
 +   */
 +  private float width = 0.0f;
 +  /**
 +   * The top y position of the footer line.
 +   */
 +  public float footer_line = 0.0f;
 +
 +  /**
 +   * The y position.
 +   */
 +  public String myposstring = "";
 +  
 +  private boolean newpage = false;
 +  private boolean autoX = true; 
 +  private boolean autoY = true;
 +  private boolean autoW = true;
 +  private boolean autoP = true;
 +  
 +  public boolean isXauto()
 +  {
 +	return this.autoX;
 +  }
 +  public boolean isYauto()
 +  {
 +	return this.autoY;
 +  } 
 +  public boolean isWauto()
 +  {
 +	return this.autoW;
 +  }
 +  public boolean isPauto()
 +  {
 +	return this.autoP;
 +  }
 +  public boolean isNewPage()
 +  {
 +	return this.newpage;
 +  }
 +  public int getPage()
 +  {
 +	return this.page;  
 +  }
 +  public float getFooterLine()
 +  {
 +	//ignore if newpage and y is not auto
 +	if (!this.autoY || this.newpage) 
 +	{
 +	  return 0.0f;
 +	}
 +	return this.footer_line;  
 +  } 
 +  public float getPosX()
 +  {
 +	return this.pos_x;  
 +  }  
 +  public float getPosY()
 +  {
 +	return this.pos_y;  
 +  } 
 +  public float getWidth()
 +  {
 +	return this.width;  
 +  }  
 +  public TablePos()
 +  {
 +    //nothing to do --> default
 +  } 
 +  
 +  /**
 +   * Constructor.
 +   * 
 +   * @param pos_string The pos instruction.
 +   *        format : [x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo]
 +   *        x_algo:='auto'     ... automatic positioning x
 +   *                floatvalue ... absolute x
 +   *        y_algo:='auto'     ... automatic positioning y
 +   *                floatvalue ... absolute y
 +   *        w_algo:='auto'     ... automatic width
 +   *                floatvalue ... absolute width    
 +   *        p_algo:='auto'     ... automatic last page
 +   *                'new'      ... new page  
 +   *                intvalue   ... pagenumber
 +   *        f_algo  floatvalue ... consider footerline (only if y_algo is auto and p_algo is not 'new')
 +   * @throws PdfAsException
 +   */
 +  public TablePos(String pos_string) throws PdfAsException
 +  {
 +    //parse posstring and throw exception
 +	//[x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo]
 +	
 +	String[] strs = pos_string.split(";");
 +	try
 +	{
 +	  for (int cmds = 0;cmds<strs.length;cmds++)
 +	  {
 +		 
 +		 String cmd_kvstring = strs[cmds];
 +		 String[] cmd_kv = cmd_kvstring.split(":");
 +		 if (cmd_kv.length != 2)
 +		 {
 +			 throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
 +		 }
 +		 String cmdstr =  cmd_kv[0];
 +		 if (cmdstr.length() != 1)
 +		 {
 +			 throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
 +		 }		 
 +		 char command = cmdstr.charAt(0);
 +	     String commandval= cmd_kv[1];
 +	     switch (command)
 +	     {
 +	     	case 'x': {
 +	     		         if (!commandval.equalsIgnoreCase("auto"))
 +	     		         {  
 +	     		        	float xval= Float.parseFloat(commandval);
 +	     		            if (xval<0)
 +	     		            {
 +	     		            	throw new PdfAsException("Pos string (x:" + xval + ") is invalid.");
 +	     		            }	     		          
 +	     		        	this.pos_x = xval;
 +	     		        	this.autoX = false; 
 +	     		         }	     		         
 +	     		         break;
 +	     			  }	
 +	     	case 'y': {
 +		         		if (!commandval.equalsIgnoreCase("auto"))
 +		         		{
 +		         			float yval= Float.parseFloat(commandval);
 +	     		            if (yval<0)
 +	     		            {
 +	     		            	throw new PdfAsException("Pos string (y:" + yval + ") is invalid.");
 +	     		            }			         			
 +		         			this.pos_y = yval;
 +		         			this.autoY = false; 
 +		         		}	     		         
 +		         		break;
 +	     			  }		
 +	     	case 'w': { 
 +         				if (!commandval.equalsIgnoreCase("auto"))
 +         				{    
 +		         			float wval= Float.parseFloat(commandval);
 +	     		            if (wval<=0)
 +	     		            {
 +	     		            	throw new PdfAsException("pos.width (w:" + wval + ") must not be lower or equal 0.");
 +	     		            }        					
 +         					this.width = wval;
 +         					this.autoW = false; 
 +         				}	     		         
 +         				break;
 +      				  }
 +	     	case 'p': {
 + 						if (!commandval.equalsIgnoreCase("auto"))
 + 						{ 
 + 							if (commandval.equalsIgnoreCase("new"))
 + 							{ 								
 + 								this.newpage = true;
 + 							}
 + 							else
 + 							{
 + 								int pval = Integer.parseInt(commandval);
 + 								if (pval<1)
 + 								{
 + 									throw new PdfAsException("Page (p:" + pval + ") must not be lower than 1.");
 + 								}
 + 								this.page = pval;
 + 								this.autoP = false;
 + 							}
 + 						}						     		       
 + 						break;
 +      				  }
 +	     	case 'f': {
 +	     		        float flval=Float.parseFloat(commandval);
 +     		            if (flval<0)
 +     		            {
 +     		            	throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
 +     		            } 	     		        
 +	     				this.footer_line = flval;
 +	     				break;
 +	     			  }
 +	     	default : {
 +		                throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
 +	                  }
 +	     }
 +	  }
 +	  this.myposstring=pos_string;
 +    }
 +    catch (NumberFormatException e)
 +    {
 +      throw new PdfAsException("Pos string (=" + pos_string + ") cannot be parsed.");
 +    }
 +  }
 +  public String toString()
 +  {  
 +	 String thatsme = "cmd:"+this.myposstring+" pos_x:"+this.pos_x+" pos_y:"+this.pos_y+" page:"+this.page+" width:"+this.width+" footer:"+this.footer_line+"\n "+" autoX:"+this.autoX+" autoY:"+this.autoY+" autoW:"+this.autoW+" Newpage:"+this.newpage+" autoP:"+this.autoP; 
 +	 return thatsme;
 +  }
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java new file mode 100644 index 00000000..63bd9481 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java @@ -0,0 +1,61 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import org.apache.pdfbox.util.operator.OperatorProcessor;
 +
 +import java.awt.geom.Point2D;
 +
 +/**
 + * Provides functions for path construction operators.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author Datentechnik Innovation GmbH
 + *
 + */
 +public abstract class PathConstructionOperatorProcessor extends OperatorProcessor {
 +
 +	public PathConstructionOperatorProcessor(PDFPage context) {
 +		setContext(context);
 +	}
 +
 +	/**
 +	 * Transforms the given point from user space coordinates to device space coordinates based on the current
 +	 * transition matrix.
 +	 *
 +	 * @param x
 +	 *            The x axis value of the user space coordinates.
 +	 * @param y
 +	 *            The y axis value of the user space coordinates.
 +	 * @return The transformed point.
 +	 */
 +	public Point2D transform(double x, double y) {
 +		double[] position = { x, y };
 +		context.getGraphicsState().getCurrentTransformationMatrix().createAffineTransform()
 +				.transform(position, 0, position, 0, 1);
 +		return new Point2D.Double(position[0], position[1]);
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java new file mode 100644 index 00000000..a0b73015 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java @@ -0,0 +1,42 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import org.apache.pdfbox.util.operator.OperatorProcessor;
 +
 +/**
 + * Provides functions for path painting operators.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author Datentechnik Innovation GmbH
 + *
 + */
 +public abstract class PathPaintingOperatorProcessor extends OperatorProcessor {
 +
 +	public PathPaintingOperatorProcessor(PDFPage context) {
 +		setContext(context);
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java new file mode 100644 index 00000000..c663fb5d --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java @@ -0,0 +1,67 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Close the current subpath by appending a straight line segment from the current point to the starting point of the
 + * subpath. If the current subpath is already closed, h shall donothing. This operator terminates the current subpath.
 + * Appending another segment to the current path shall begin a new subpath, even if the new segment begins at the
 + * endpoint reached by the h operation.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class ClosePath extends PathConstructionOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public ClosePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			pdfPage.getCurrentPath().closePath();
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Closing current path.");
 +			}
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'h'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java new file mode 100644 index 00000000..70f5ab20 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java @@ -0,0 +1,84 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.cos.COSNumber;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.Point2D;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
 + * using (x1, y1) and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
 + * shall be (x3, y3).
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class CurveTo extends PathConstructionOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public CurveTo(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			COSNumber x1 = (COSNumber) operands.get(0);
 +			COSNumber y1 = (COSNumber) operands.get(1);
 +			COSNumber x2 = (COSNumber) operands.get(2);
 +			COSNumber y2 = (COSNumber) operands.get(3);
 +			COSNumber x3 = (COSNumber) operands.get(4);
 +			COSNumber y3 = (COSNumber) operands.get(5);
 +
 +			Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
 +			Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
 +			Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
 +
 +			pdfPage.getCurrentPath().curveTo(
 +					(float) p1.getX(), (float) p1.getY(),
 +					(float) p2.getX(), (float) p2.getY(),
 +					(float) p3.getX(), (float) p3.getY()
 +			);
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x2:"
 +						+ p2.getX() + ",y2:" + p2.getY() + ", x3:" + p3.getX() + ",y3:" + p3.getY());
 +			}
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'c'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java new file mode 100644 index 00000000..c6125751 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java @@ -0,0 +1,81 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.cos.COSNumber;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.Point2D;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
 + * using (x1, y1) and (x3, y3) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
 + * shall be (x3, y3).
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class CurveToReplicateFinalPoint extends PathConstructionOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public CurveToReplicateFinalPoint(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			COSNumber x1 = (COSNumber) operands.get(0);
 +			COSNumber y1 = (COSNumber) operands.get(1);
 +			COSNumber x3 = (COSNumber) operands.get(2);
 +			COSNumber y3 = (COSNumber) operands.get(3);
 +
 +			Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
 +			Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
 +
 +			pdfPage.getCurrentPath().curveTo(
 +					(float) p1.getX(), (float) p1.getY(),
 +					(float) p3.getX(), (float) p3.getY(),
 +					(float) p3.getX(), (float) p3.getY()
 +			);
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x3:"
 +						+ p3.getX() + ",y3:" + p3.getY());
 +			}
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'y'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java new file mode 100644 index 00000000..1479bc7d --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java @@ -0,0 +1,83 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.cos.COSNumber;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.Point2D;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
 + * using the current point and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new
 + * current point shall be (x3, y3).
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class CurveToReplicateInitialPoint extends PathConstructionOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public CurveToReplicateInitialPoint(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			COSNumber x2 = (COSNumber) operands.get(0);
 +			COSNumber y2 = (COSNumber) operands.get(1);
 +			COSNumber x3 = (COSNumber) operands.get(2);
 +			COSNumber y3 = (COSNumber) operands.get(3);
 +
 +	        Point2D currentPoint = pdfPage.getCurrentPath().getCurrentPoint();
 +			Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
 +			Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
 +
 +			pdfPage.getCurrentPath().curveTo(
 +					(float)currentPoint.getX(), (float)currentPoint.getY(),
 +					(float) p2.getX(), (float) p2.getY(),
 +					(float) p3.getX(), (float) p3.getY()
 +			);
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Appending cubic Bezier curve with x2:" + p2.getX() + ",y2:" + p2.getY() + ", x3:"
 +						+ p3.getX() + ",y3:" + p3.getY() + ", using current point x:" + currentPoint.getX() + ",y:"
 +						+ currentPoint.getY());
 +			}
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'v'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java new file mode 100644 index 00000000..94f16b7f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java @@ -0,0 +1,70 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.cos.COSNumber;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.Point2D;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Append a straight line segment from the current point to the point (x, y). The new current point shall be (x, y).
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class LineTo extends PathConstructionOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public LineTo(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			COSNumber x = (COSNumber) operands.get(0);
 +			COSNumber y = (COSNumber) operands.get(1);
 +			Point2D p = transform(x.doubleValue(), y.doubleValue());
 +
 +			pdfPage.getCurrentPath().lineTo((float) p.getX(), (float) p.getY());
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Adding line to x:" + p.getX() + ",y:" + p.getY());
 +			}
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'l'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java new file mode 100644 index 00000000..97424e93 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java @@ -0,0 +1,72 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.cos.COSNumber;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.Point2D;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment. If the
 + * previous path construction operator in the current path was also m, the new m overrides it; no vestige of the
 + * previous m operation remains in the path.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class MoveTo extends PathConstructionOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public MoveTo(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			COSNumber x = (COSNumber) operands.get(0);
 +			COSNumber y = (COSNumber) operands.get(1);
 +			Point2D p = transform(x.doubleValue(), y.doubleValue());
 +
 +			pdfPage.getCurrentPath().moveTo((float) p.getX(), (float) p.getY());
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Moving current path to x:" + p.getX() + ",y:" + p.getY());
 +			}
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'm'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java new file mode 100644 index 00000000..5a8de9d0 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java @@ -0,0 +1,58 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Close and stroke the path. This operator shall have the same effect as the sequence <code>h S</code>.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class CloseAndStrokePath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public CloseAndStrokePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		if (log.isTraceEnabled()) {
 +			log.trace("Closing and stroking path.");
 +		}
 +		context.processOperator("h", operands);
 +		context.processOperator("S", operands);
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java new file mode 100644 index 00000000..bdaaaa4a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java @@ -0,0 +1,59 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall
 + * have the same effect as the sequence <code>h B*</code>.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class CloseFillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public CloseFillEvenOddAndStrokePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		if (log.isTraceEnabled()) {
 +			log.trace("Closing, filling (even odd rule) and stroking path.");
 +		}
 +		context.processOperator("h", operands);
 +		context.processOperator("B*", operands);
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java new file mode 100644 index 00000000..4d4f3b68 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java @@ -0,0 +1,59 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill. This
 + * operator shall have the same effect as the sequence <code>h B</code>.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class CloseFillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public CloseFillNonZeroAndStrokePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		if (log.isTraceEnabled()) {
 +			log.trace("Closing, filling (non zero rule) and stroking path.");
 +		}
 +		context.processOperator("h", operands);
 +		context.processOperator("B", operands);
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java new file mode 100644 index 00000000..291175aa --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java @@ -0,0 +1,67 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * End the path object without filling or stroking it. This operator shall be a path-painting no-op, used primarily for
 + * the side effect of changing the current clipping path.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class EndPath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public EndPath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			log.debug("Ending path " + pdfPage.getCurrentPath());
 +			pdfPage.getCurrentPath().reset();
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("End path without filling or stroking.");
 +			}
 +
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'n'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java new file mode 100644 index 00000000..b1e836d5 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java @@ -0,0 +1,71 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.GeneralPath;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Fill and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall produce
 + * the same result as <code>B</code>, except that the path is filled as if with <code>f*</code> instead of
 + * <code>f</code>.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class FillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public FillEvenOddAndStrokePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Filling (even odd rule) and stroking path.");
 +			}
 +
 +			GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
 +			context.processOperator("f*", operands);
 +			pdfPage.setCurrentPath(currentPath);
 +			context.processOperator("S", operands);
 +
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'B*'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java new file mode 100644 index 00000000..72719ec3 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java @@ -0,0 +1,71 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.geom.GeneralPath;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill. This operator
 + * shall produce the same result as constructing two identical path objects, painting the first with <code>f</code> and
 + * the second with <code>S</code>.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class FillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public FillNonZeroAndStrokePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Filling (non zero rule) and stroking path.");
 +			}
 +
 +			GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
 +			context.processOperator("f", operands);
 +			pdfPage.setCurrentPath(currentPath);
 +			context.processOperator("S", operands);
 +
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'B'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java new file mode 100644 index 00000000..28343c5a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java @@ -0,0 +1,70 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.*;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Fill the path, using the even-odd rule to determine the region to fill.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class FillPathEvenOddRule extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public FillPathEvenOddRule(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_EVEN_ODD);
 +			Rectangle bounds = pdfPage.getCurrentPath().getBounds();
 +			pdfPage.getCurrentPath().reset();
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Filling path, using even-odd rule.");
 +			}
 +
 +			pdfPage.registerPathBounds(bounds);
 +
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'f*'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java new file mode 100644 index 00000000..28e5c373 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java @@ -0,0 +1,71 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.*;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Fill the path, using the nonzero winding number rule to determine the region to fill. Any subpaths that are open
 + * shall be implicitly closed before being filled.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class FillPathNonZeroWindingNumberRule extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public FillPathNonZeroWindingNumberRule(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_NON_ZERO);
 +			Rectangle bounds = pdfPage.getCurrentPath().getBounds();
 +			pdfPage.getCurrentPath().reset();
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Filling path, using nonzero winding number rule.");
 +			}
 +
 +			pdfPage.registerPathBounds(bounds);
 +
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'f/F'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java new file mode 100644 index 00000000..0530a925 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java @@ -0,0 +1,69 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
 +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.util.PDFOperator;
 +
 +import java.awt.*;
 +import java.io.IOException;
 +import java.util.List;
 +
 +/**
 + * Strokes the path.
 + *
 + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
 + * @author PdfBox, modified by Datentechnik Innovation GmbH
 + */
 +public class StrokePath extends PathPaintingOperatorProcessor {
 +
 +	private Log log = LogFactory.getLog(getClass());
 +
 +	public StrokePath(PDFPage context) {
 +		super(context);
 +	}
 +
 +	@Override
 +	public void process(PDFOperator operator, List operands) throws IOException {
 +		try {
 +			PDFPage pdfPage = (PDFPage) context;
 +
 +			Rectangle bounds = pdfPage.getCurrentPath().getBounds();
 +			pdfPage.getCurrentPath().reset();
 +
 +			if (log.isTraceEnabled()) {
 +				log.trace("Stroking path.");
 +			}
 +
 +			pdfPage.registerPathBounds(bounds);
 +
 +		} catch (Exception e) {
 +			log.warn("Error processing operator 'S'.", e);
 +		}
 +	}
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java new file mode 100644 index 00000000..957e947f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java @@ -0,0 +1,163 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: SignatureEntry.java,v 1.3 2006/08/25 17:09:41 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.pdf.sig;
 +
 +import java.io.Serializable;
 +
 +/**
 + * This class is to store a signature entry. The signature entry is 3-tupel. A key that is defined
 + * or declarated in the settings file, an optional caption or a value. <br>
 + * An additional helper value is a marker for the start index of the key, if the key is found in an
 + * analysing process extracting captions and values from a raw signature text.
 + * 
 + * @author wlackner
 + * @see at.knowcenter.wag.egov.egiz.sig.SignatureObject
 + */
 +public class SignatureEntry implements Serializable {
 +
 +  /**
 +   * SVUID.
 +   */
 +  private static final long serialVersionUID = 4640380069301731879L;
 +  
 +  /**
 +   * The signature key.
 +   */
 +  private String key_ = null;
 +  /**
 +   * The signature caption for the key found or set in the signature text.
 +   */
 +  private String caption_ = null;
 +  /**
 +   * The signature value for the key found or set in the signature text.
 +   */
 +  private String value_ = null;
 +  /**
 +   * The starting index position of the key if it is found in the signature text.
 +   */
 +  private int startIndex_ = -1;
 +  
 +  public boolean isPlaceholder = false;
 +
 +  /**
 +   * The empty constructor.
 +   */
 +  public SignatureEntry() {
 +  }
 +
 +  /**
 +   * A new <code>SignatureEntry</code> init with the key.
 +   * 
 +   * @param key
 +   */
 +  public SignatureEntry(String key) {
 +    key_ = key;
 +  }
 +
 +  /**
 +   * Returns the caption off the current key.
 +   * 
 +   * @return Returns the caption.
 +   */
 +  public String getCaption() {
 +    return caption_;
 +  }
 +
 +  /**
 +   * Set the caption of the current key.
 +   * 
 +   * @param caption The caption to set.
 +   */
 +  public void setCaption(String caption) {
 +    caption_ = caption;
 +  }
 +
 +  /**
 +   * Return the current key.
 +   * 
 +   * @return Returns the key.
 +   */
 +  public String getKey() {
 +    return key_;
 +  }
 +
 +  /**
 +   * Set the current key.
 +   * 
 +   * @param key The key to set.
 +   */
 +  public void setKey(String key) {
 +    key_ = key;
 +  }
 +
 +  /**
 +   * Return the start position of the key that caption is found in the signature text.
 +   * 
 +   * @return Returns the startIndex.
 +   */
 +  public int getStartIndex() {
 +    return startIndex_;
 +  }
 +
 +  /**
 +   * Set the start position of the current key.
 +   * 
 +   * @param startIndex The startIndex to set.
 +   */
 +  public void setStartIndex(int startIndex) {
 +    startIndex_ = startIndex;
 +  }
 +
 +  /**
 +   * Return the value of the current key.
 +   * 
 +   * @return Returns the value.
 +   */
 +  public String getValue() {
 +    return value_;
 +  }
 +
 +  /**
 +   * Set the value of the current key.
 +   * 
 +   * @param value The value to set.
 +   */
 +  public void setValue(String value) {
 +    value_ = value;
 +  }
 +
 +  /**
 +   * The toString method, used for tests or debugging.
 +   */
 +  public String toString() {
 +    String the_string = "";
 +    the_string += "\n    Key:" + key_;
 +    the_string += "\nCaption:" + caption_;
 +    the_string += "\n  Value:" + value_;
 +//    the_string += "\nStart I:" + startIndex_;
 +    return the_string;
 +  }
 +}
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java new file mode 100644 index 00000000..289a7f6f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java @@ -0,0 +1,235 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: Entry.java,v 1.3 2006/08/25 17:08:19 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.table;
 +
 +import java.io.Serializable;
 +
 +/**
 + * This class implements a table entry for different types. A table entry can be
 + * styled and setting there column dimensions. The default value for the column
 + * dimension is 1. To declare the type of the entry use the public
 + * <code>TYPE_</code> definitions.
 + * 
 + * @author wlackner
 + */
 +public class Entry implements Serializable
 +{
 +
 +  /**
 +   * SVUID.
 +   */
 +  private static final long serialVersionUID = -7952755200668528348L;
 +
 +  /**
 +   * Type for a text entry.
 +   */
 +  public final static int TYPE_CAPTION = 0;
 +
 +  /**
 +   * Type for a text entry.
 +   */
 +  public final static int TYPE_VALUE = 1;
 +
 +  /**
 +   * Type for an image entry.
 +   */
 +  public final static int TYPE_IMAGE = 2;
 +
 +  /**
 +   * Type for a table entry.
 +   */
 +  public final static int TYPE_TABLE = 3;
 +
 +  /**
 +   * The type info holder, default value is 0!
 +   */
 +  private int type_ = 0;
 +
 +  /**
 +   * The entry value.
 +   */
 +  private Object value_ = null;
 +
 +  /**
 +   * The key value
 +   */
 +  private String key_ = null;
 +
 +  /**
 +   * The entry style information.
 +   */
 +  private Style style_ = null;
 +
 +  /**
 +   * The column dimension.
 +   */
 +  private int colSpan_ = 1;
 +
 +  /**
 +   * Text wrap indicator, default is <code>false</code>.
 +   */
 +  private boolean noWrap_ = false;
 +
 +  /**
 +   * The empty constructor.
 +   */
 +  public Entry()
 +  {
 +  }
 +
 +  /**
 +   * A constructor setting the type and the value.
 +   * 
 +   * @param type
 +   *          the entry type to set
 +   * @param value
 +   *          the entry value to set
 +   */
 +  public Entry(int type, Object value, String key)
 +  {
 +    type_ = type;
 +    value_ = value;
 +    key_ = key;
 +  }
 +
 +  /**
 +   * @return Returns the entry style.
 +   */
 +  public Style getStyle()
 +  {
 +    return style_;
 +  }
 +
 +  /**
 +   * @param style
 +   *          The style to set.
 +   */
 +  public void setStyle(Style style)
 +  {
 +    style_ = style;
 +  }
 +
 +  /**
 +   * @return Returns the entry type.
 +   */
 +  public int getType()
 +  {
 +    return type_;
 +  }
 +
 +  /**
 +   * @param type
 +   *          The type to set.
 +   */
 +  public void setType(int type)
 +  {
 +    type_ = type;
 +  }
 +
 +  /**
 +   * @return Returns the entry value.
 +   */
 +  public Object getValue()
 +  {
 +    return value_;
 +  }
 +
 +  /**
 +   * @param value
 +   *          The value to set.
 +   */
 +  public void setValue(Object value)
 +  {
 +    value_ = value;
 +  }
 +
 +  /**
 +   * @return Returns the key.
 +   */
 +
 +  public String getKey()
 +  {
 +    return key_;
 +  }
 +
 +  /**
 +   * @param key
 +   *          The key to set.
 +   */
 +  public void setKey(String key)
 +  {
 +    key_ = key;
 +  }
 +
 +  /**
 +   * @return Returns the colSpan.
 +   */
 +  public int getColSpan()
 +  {
 +    return colSpan_;
 +  }
 +
 +  /**
 +   * @param colSpan
 +   *          The colSpan to set.
 +   */
 +  public void setColSpan(int colSpan)
 +  {
 +    colSpan_ = colSpan;
 +  }
 +
 +  /**
 +   * @return Returns the wrap indicator.
 +   */
 +  public boolean isNoWrap()
 +  {
 +    return noWrap_;
 +  }
 +
 +  /**
 +   * @param noWrap
 +   *          The wrap indicator to set.
 +   */
 +  public void setNoWrap(boolean noWrap)
 +  {
 +    noWrap_ = noWrap;
 +  }
 +
 +  /**
 +   * The toString method, used for tests or debugging.
 +   */
 +  public String toString()
 +  {
 +    Object obj = getValue();
 +    String value = null;
 +    if (obj != null)
 +    {
 +      value = obj.toString();
 +    }
 +    return "Type:" + getType() + " Value:" + value + " ColSpan:" + getColSpan();
 +  }
 +
 +}
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java new file mode 100644 index 00000000..489c9419 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java @@ -0,0 +1,630 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: Style.java,v 1.3 2006/08/25 17:08:19 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.table;
 +
 +import java.awt.Color;
 +import java.io.Serializable;
 +
 +/**
 + * This class implements an abstract style definiton used in tables or table entrys. Predefined
 + * values exists for valign and halign. Color definitions uses the native awt color declarations.
 + * <br>
 + * The predefined keys are used in the setting definition file to style tables and table entries.
 + * <br>
 + * It provides an static method to inherit style informations from a given style object.
 + * {@link Style#doInherit}
 + * 
 + * 
 + * @author wlackner
 + * @see java.awt.Color
 + */
 +public class Style implements Serializable {
 +
 +// 03.11.2010 changed by exthex - added valuevalign and valuehalign to allow separate layout for value and non-value cells.
 +// Also the hardcoded default values for halign and valign were removed to allow proper inheritment.
 +// 04.11.2010 changed by exthex - added imagevalign and imagehalign analog to valuevalign/valuehalign
 +
 +  /**
 +   * SVUID.
 +   */
 +  private static final long serialVersionUID = 5855722896712428387L;
 +  
 +  /**
 +   * valign statement key top
 +   */
 +  public final static String TOP = "top";
 +  /**
 +   * valign statement key middle
 +   */
 +  public final static String MIDDLE = "middle";
 +  /**
 +   * valign statement key bottom
 +   */
 +  public final static String BOTTOM = "bottom";
 +  /**
 +   * halign statement key left
 +   */
 +  public final static String LEFT = "left";
 +  /**
 +   * halign statement key center
 +   */
 +  public final static String CENTER = "center";
 +  /**
 +   * halign statement key right
 +   */
 +  public final static String RIGHT = "right";
 +
 +  /**
 +   * bgcolor key
 +   */
 +  public final static String BGCOLOR = "bgcolor";
 +  /**
 +   * halign key
 +   */
 +  public final static String HALIGN = "halign";
 +  /**
 +   * valign key
 +   */
 +  public final static String VALIGN = "valign";
 +
 +  /**
 +   * value halign key
 +   */
 +  public final static String VALUEHALIGN = "valuehalign";
 +  /**
 +   * value valign key
 +   */
 +  public final static String VALUEVALIGN = "valuevalign";
 +
 +  /**
 +   * image halign key
 +   */
 +  public final static String IMAGEHALIGN = "imagehalign";
 +  /**
 +   * image valign key
 +   */
 +  public final static String IMAGEVALIGN = "imagevalign";
 +  /**
 +   * padding key, default padding = 1
 +   */
 +  public final static String PADDING = "padding";
 +  /**
 +   * border key, default border = 1;<br>
 +   * The border value is one value for all border lines of an entry or table! <br>
 +   * No separte definitions for top, right, bottom or left are possible.
 +   */
 +  public final static String BORDER = "border";
 +  
 +  /**
 +   * Font key
 +   */
 +  public final static String FONT = "font";
 +  
 +  /**
 +   * The value font key.
 +   */
 +  public final static String VALUEFONT = "valuefont";
 +  
 +  /**
 +   * The imageScaleToFit key.
 +   */
 +  public final static String IMAGE_SCALE_TO_FIT = "imagescaletofit";
 +  
 +  /**
 +   * Font name HELVETICA
 +   */
 +  public final static String HELVETICA = "HELVETICA";
 +  /**
 +   * Font name TIMES_ROMAN
 +   */
 +  public final static String TIMES_ROMAN = "TIMES_ROMAN";
 +  /**
 +   * Font name COURIER
 +   */
 +  public final static String COURIER = "COURIER";
 +  /**
 +   * Font type NORMAL
 +   */
 +  public final static String NORMAL = "NORMAL";
 +  /**
 +   * Font type BOLD
 +   */
 +  public final static String BOLD = "BOLD";
 +  /**
 +   * Font type ITALIC
 +   */
 +  public final static String ITALIC = "ITALIC";
 +  /**
 +   * Font type BOLDITALIC
 +   */
 +  public final static String BOLDITALIC = "BOLDITALIC";
 +  /**
 +   * Font type UNDERLINE
 +   */
 +  public final static String UNDERLINE = "UNDERLINE";
 +  /**
 +   * Font type STRIKETHRU
 +   */
 +  public final static String STRIKETHRU = "STRIKETHRU";
 +  
 +
 +  /**
 +   * all paddings initialized with the default padding value (1)
 +   */
 +  private static final float DEFAULT_PADDING = 1;
 +  /**
 +   * all borders initialized with the default border value (1)
 +   */
 +  private static final float DEFAULT_BORDER = 1;
 +  /**
 +   * The background color definition.
 +   */
 +  private Color bgColor_ = null;
 +  /**
 +   * The current padding value -> initialized with the default padding value
 +   */
 +  private float padding_ = DEFAULT_PADDING;
 +  /**
 +   * The current halign value
 +   */
 +  private String hAlign_ = null;
 +  /**
 +   * The current valign value
 +   */
 +  private String vAlign_ = null;
 +  /**
 +   * The current valuehalign value
 +   */
 +  private String valueHAlign_ = null;
 +  /**
 +   * The current valuevalign value
 +   */
 +  private String valueVAlign_ = null;
 +  /**
 +   * The current imagehalign value
 +   */
 +  private String imageHAlign_ = null;
 +  /**
 +   * The current imagevalign value
 +   */
 +  private String imageVAlign_ = null;
 +  /**
 +   * The current border value -> initialized with the default border value
 +   */
 +  private float border_ = DEFAULT_BORDER;
 +  /**
 +   * The font string of the style definition
 +   */
 +  private String font_ = null;
 +  /**
 +   * The font string of the value font.
 +   */
 +  private String valuefont_ = null;
 +  /**
 +   * The scaleToFit dimensions to be applied for image-cells.
 +   */
 +  private ImageScaleToFit imageScaleToFit_ = null;
 +
 +  /**
 +   * The empty constructor.
 +   */
 +  public Style() {
 +  }
 +
 +  /**
 +   * Set a style attribute. The style attribute must be one of the public definitions
 +   * 
 +   * @param id the style attribute to set
 +   * @param value the style value to set for the given attribute
 +   */
 +  public void setStyle(String id, String value) {
 +    if (BGCOLOR.equals(id)) {
 +      String[] col_strg = value.split(" ");
 +      if (col_strg.length == 3) {
 +        int r = Integer.parseInt(col_strg[0]);
 +        int g = Integer.parseInt(col_strg[1]);
 +        int b = Integer.parseInt(col_strg[2]);
 +        if (r < 256 && g < 256 && b < 256 && r >= 0 && g >= 0 && b >= 0) {
 +          bgColor_ = new Color(r, g, b);
 +        }
 +      }
 +    }
 +    if (HALIGN.equals(id)) {
 +      if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) {
 +        hAlign_ = value;
 +      }
 +    }
 +    if (VALIGN.equals(id)) {
 +      if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) {
 +        vAlign_ = value;
 +      }
 +    }
 +    if (VALUEHALIGN.equals(id)) {
 +      if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) {
 +        valueHAlign_ = value;
 +      }
 +    }
 +    if (VALUEVALIGN.equals(id)) {
 +      if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) {
 +        valueVAlign_ = value;
 +      }
 +    }
 +    if (IMAGEHALIGN.equals(id)) {
 +      if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) {
 +        imageHAlign_ = value;
 +      }
 +    }
 +    if (IMAGEVALIGN.equals(id)) {
 +      if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) {
 +        imageVAlign_ = value;
 +      }
 +    }
 +    if (PADDING.equals(id)) {
 +      padding_ = Float.parseFloat(value);
 +    }
 +    if (BORDER.equals(id)) {
 +      border_ = Float.parseFloat(value);
 +    }
 +    if (FONT.equals(id)) {
 +      font_ = value;
 +    }
 +    if (VALUEFONT.equals(id)) {
 +      valuefont_ = value;
 +    }
 +    if (IMAGE_SCALE_TO_FIT.equals(id))
 +    {
 +      imageScaleToFit_ = parseImageScaleToFit(value);
 +    }
 +  }
 +
 +  /**
 +   * @return Returns the bgColor.
 +   */
 +  public Color getBgColor() {
 +    return bgColor_;
 +  }
 +
 +  /**
 +   * @param bgColor The bgColor to set.
 +   */
 +  public void setBgColor(Color bgColor) {
 +    bgColor_ = bgColor;
 +  }
 +
 +  /**
 +   * @return Returns the hAlign.
 +   */
 +  public String getHAlign() {
 +    return hAlign_;
 +  }
 +
 +  /**
 +   * @param align The hAlign to set.
 +   */
 +  public void setHAlign(String align) {
 +    hAlign_ = align;
 +  }
 +
 +  /**
 +   * @return Returns the padding.
 +   */
 +  public float getPadding() {
 +    return padding_;
 +  }
 +
 +  /**
 +   * @param padding The padding to set.
 +   */
 +  public void setPadding(float padding) {
 +    padding_ = padding;
 +  }
 +
 +  /**
 +   * @return Returns the vAlign.
 +   */
 +  public String getVAlign() {
 +    return vAlign_;
 +  }
 +
 +  /**
 +   * @param align The vAlign to set.
 +   */
 +  public void setVAlign(String align) {
 +    vAlign_ = align;
 +  }
 +
 +  /**
 +   * @return Returns the border.
 +   */
 +  public float getBorder() {
 +    return border_;
 +  }
 +
 +  /**
 +   * @param border The border to set.
 +   */
 +  public void setBorder(float border) {
 +    border_ = border;
 +  }
 +
 +  
 +  /**
 +   * @return Returns the font.
 +   */
 +  public String getFont() {
 +    return font_;
 +  }
 +  
 +  /**
 +   * @param font The font to set.
 +   */
 +  public void setFont(String font) {
 +    font_ = font;
 +  }
 +  
 +  
 +  /**
 +   * Returns the value font.
 +   * @return Returns the value font.
 +   */
 +  public String getValueFont()
 +  {
 +    return valuefont_;
 +  }
 +
 +  /**
 +   * Sets the value font.
 +   * @param valuefont The value font to be set.
 +   */
 +  public void setValueFont(String valuefont)
 +  {
 +    this.valuefont_ = valuefont;
 +  }
 +  
 +  /**
 +   * @param align The valueHAlign to set.
 +   */
 +  public void setValueHAlign(String align) {
 +    valueHAlign_ = align;
 +  }
 +
 +  /**
 +   * Returns the value halign
 +   * @return Returns the value halign
 +   */
 +  public String getValueHAlign() {
 +    return valueHAlign_;
 +  }
 +
 +  /**
 +   * @param align The valueVAlign to set.
 +   */
 +  public void setValueVAlign(String align) {
 +    valueVAlign_ = align;
 +  }
 +
 +  /**
 +   * Returns the value valign
 +   * @return Returns the value valign
 +   */
 +  public String getValueVAlign() {
 +    return valueVAlign_;
 +  }
 +  
 +  /**
 +   * @param align The imageHAlign to set.
 +   */
 +  public void setImageHAlign(String align) {
 +    imageHAlign_ = align;
 +  }
 +
 +  /**
 +   * Returns the image halign
 +   * @return Returns the image halign
 +   */
 +  public String getImageHAlign() {
 +    return imageHAlign_;
 +  }
 +
 +  /**
 +   * @param align The imageVAlign to set.
 +   */
 +  public void setImageVAlign(String align) {
 +    imageVAlign_ = align;
 +  }
 +
 +  /**
 +   * Returns the image valign
 +   * @return Returns the image valign
 +   */
 +  public String getImageVAlign() {
 +    return imageVAlign_;
 +  }
 +
 +  /**
 +   * Returns the scaleToFit dimensions to be applied for image-cells.
 +   * @return Returns the scaleToFit dimensions to be applied for image-cells.
 +   */
 +  public ImageScaleToFit getImageScaleToFit()
 +  {
 +    return this.imageScaleToFit_;
 +  }
 +
 +  /**
 +   * Sets the scaleToFit dimensions to be applied for image-cells.
 +   * @param imageScaleToFit_ The scaleToFit dimensions to be applied for image-cells.
 +   */
 +  public void setImageScaleToFit(ImageScaleToFit imageScaleToFit)
 +  {
 +    this.imageScaleToFit_ = imageScaleToFit;
 +  }
 +
 +  /**
 +   * The toString method, used for tests or debugging.
 +   */
 +  public String toString() {
 +    return "bgcolor:" + getBgColor() + " halign:" + getHAlign() + " valign:" + getVAlign() + " padding:" + getPadding() + " border:" + getBorder() + " font:" + getFont() + " valuefont:" + getValueFont() + " imageScaleToFit:" + getImageScaleToFit();
 +  }
 +
 +  /**
 +   * This method inherits all style attributes (values) from a given style object.
 +   * 
 +   * <p>
 +   * A new style object is created that receives the properly inherited styles.
 +   * </p>
 +   * <p>
 +   * If a value is not defined in the <code>baseStyle</code> object it would be inhert from the <code>inheritStyle</code> object.
 +   * </p>
 +   * 
 +   * @param baseStyle the style object that serves as a primary style source.
 +   * @param inheritStyle the style object that serves as a secondary style source in case a style attribute is not defined on the primary style source. 
 +   * @param isValue 
 +   * @return Returns a new Style object being fully equipped with styles.
 +   */
 +  public static Style doInherit(Style baseStyle, Style inheritStyle) {
 +    Style newStyle = new Style();
 +    
 +    if (baseStyle != null)
 +    {
 +      newStyle.setBgColor(baseStyle.getBgColor());
 +      newStyle.setBorder(baseStyle.getBorder());
 +      newStyle.setFont(baseStyle.getFont());
 +      newStyle.setHAlign(baseStyle.getHAlign());
 +      newStyle.setImageHAlign(baseStyle.getImageHAlign());
 +      newStyle.setImageVAlign(baseStyle.getImageVAlign());
 +      newStyle.setPadding(baseStyle.getPadding());
 +      newStyle.setVAlign(baseStyle.getVAlign());
 +      newStyle.setValueFont(baseStyle.getValueFont());
 +      newStyle.setValueHAlign(baseStyle.getValueHAlign());
 +      newStyle.setValueVAlign(baseStyle.getValueVAlign());
 +      newStyle.setImageScaleToFit(baseStyle.getImageScaleToFit());
 +    }
 +    
 +    if (inheritStyle != null)
 +    {
 +      if (newStyle.getBgColor() == null) { newStyle.setBgColor(inheritStyle.getBgColor()); }
 +      if (newStyle.getBorder() == DEFAULT_BORDER) { newStyle.setBorder(inheritStyle.getBorder()); }
 +      if (newStyle.getFont() == null) { newStyle.setFont(inheritStyle.getFont()); }
 +      if (newStyle.getHAlign() == null) { newStyle.setHAlign(inheritStyle.getHAlign()); }
 +      if (newStyle.getImageHAlign() == null) { newStyle.setImageHAlign(inheritStyle.getImageHAlign()); }
 +      if (newStyle.getImageVAlign() == null) { newStyle.setImageVAlign(inheritStyle.getImageVAlign()); }
 +      if (newStyle.getPadding() == DEFAULT_PADDING) { newStyle.setPadding(inheritStyle.getPadding()); }
 +      if (newStyle.getVAlign() == null) { newStyle.setVAlign(inheritStyle.getVAlign()); }
 +      if (newStyle.getValueFont() == null) { newStyle.setValueFont(inheritStyle.getValueFont()); }
 +      if (newStyle.getValueHAlign() == null) { newStyle.setValueHAlign(inheritStyle.getValueHAlign()); }
 +      if (newStyle.getValueVAlign() == null) { newStyle.setValueVAlign(inheritStyle.getValueVAlign()); }
 +      if (newStyle.getImageScaleToFit() == null) { newStyle.setImageScaleToFit(inheritStyle.getImageScaleToFit()); }
 +   }
 +    
 +   return newStyle;
 +  }
 +  
 +  protected static ImageScaleToFit parseImageScaleToFit (String imageScaleToFit)
 +  {
 +    if (imageScaleToFit == null || imageScaleToFit.length() == 0 || imageScaleToFit.trim().length() == 0)
 +    {
 +      return null;
 +    }
 +    
 +    String [] dimensions = imageScaleToFit.split(";");
 +    if (dimensions.length != 2)
 +    {
 +      return null;
 +    }
 +    
 +    float width = Float.parseFloat(dimensions[0]);
 +    float height = Float.parseFloat(dimensions[0]);
 +    
 +    return new ImageScaleToFit(width, height);
 +  }
 +  
 +  /**
 +   * Holds the width and the height an image can be scaled to fit.
 +   * 
 +   * @author wprinz
 +   */
 +  public static class ImageScaleToFit
 +  {
 +    /**
 +     * The width.
 +     */
 +    protected float width;
 +    
 +    /**
 +     * The height.
 +     */
 +    protected float height;
 +
 +    /**
 +     * Constructor.
 +     * 
 +     * @param width The width.
 +     * @param height The height.
 +     */
 +    public ImageScaleToFit(float width, float height)
 +    {
 +      this.width = width;
 +      this.height = height;
 +    }
 +
 +    /**
 +     * Returns the width.
 +     * @return Returns the width.
 +     */
 +    public float getWidth()
 +    {
 +      return this.width;
 +    }
 +
 +    /**
 +     * Sets the width.
 +     * @param width The width to set.
 +     */
 +    public void setWidth(float width)
 +    {
 +      this.width = width;
 +    }
 +
 +    /**
 +     * Returns the height.
 +     * @return Returns the height.
 +     */
 +    public float getHeight()
 +    {
 +      return this.height;
 +    }
 +
 +    /**
 +     * Sets the height.
 +     * @param height The height to set.
 +     */
 +    public void setHeight(float height)
 +    {
 +      this.height = height;
 +    }
 +     
 +  }
 +}
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java new file mode 100644 index 00000000..c5a0c58f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java @@ -0,0 +1,223 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + *
 + * $Id: Table.java,v 1.2 2006/08/25 17:08:19 wprinz Exp $
 + */
 +package at.knowcenter.wag.egov.egiz.table;
 +
 +import java.io.Serializable;
 +import java.util.Map;
 +import java.util.HashMap;
 +import java.util.ArrayList;
 +
 +/**
 + * This class implements an abstract table definition. The table contains table
 + * rows and the table rows contains the table entries. A table can be styled and
 + * a relative column width can be set.
 + * 
 + * @author wlackner
 + * @see Style
 + * @see at.knowcenter.wag.egov.egiz.table.Entry
 + */
 +public class Table implements Serializable
 +{
 +
 +  /**
 +   * SVUID.
 +   */
 +  private static final long serialVersionUID = 8488947943674086618L;
 +
 +  /**
 +   * The table column settings.
 +   */
 +  private float[] colsRelativeWith_ = null;
 +
 +  /**
 +   * The row definitions.
 +   */
 +  private Map rows_ = new HashMap();
 +
 +  /**
 +   * The table width.
 +   */
 +  private float width_ = 100;
 +
 +  /**
 +   * The table style.
 +   */
 +  private Style style_ = null;
 +
 +  /**
 +   * Number of columns that are defined for the current table.
 +   */
 +  private int maxCols_ = 0;
 +
 +  /**
 +   * A table name.
 +   */
 +  private String name_ = null;
 +
 +  /**
 +   * The table constructor init by a table name.
 +   * 
 +   * @param name
 +   *          the name for the table.
 +   */
 +  public Table(String name)
 +  {
 +    name_ = name;
 +  }
 +
 +  /**
 +   * The width of the columns are relative to each other. This means the values
 +   * are summarized and divided into portions of columns used. <br>
 +   * Example: <code>[1,4]</code> means the second column is four times wider
 +   * than the first column.
 +   * 
 +   * @return Returns the relative width of the columns
 +   */
 +  public float[] getColsRelativeWith()
 +  {
 +    return colsRelativeWith_;
 +  }
 +
 +  /**
 +   * The width of the columns are relative to each other. This means the values
 +   * are summarized and divided into portions of columns used. <br>
 +   * Example: <code>[10,90]</code> means the first colum consumes 10% and the
 +   * second column consumes 90% of the table width. <br>
 +   * The relative width of the columns to set.
 +   */
 +  public void setColsRelativeWith(float[] cols)
 +  {
 +    colsRelativeWith_ = cols;
 +  }
 +
 +  /**
 +   * @return Returns the style.
 +   */
 +  public Style getStyle()
 +  {
 +    return style_;
 +  }
 +
 +  /**
 +   * @param style
 +   *          The style to set.
 +   */
 +  public void setStyle(Style style)
 +  {
 +    style_ = style;
 +  }
 +
 +  /**
 +   * @return Returns the width.
 +   */
 +  public float getWidth()
 +  {
 +    return width_;
 +  }
 +
 +  /**
 +   * @param width
 +   *          The width to set.
 +   */
 +  public void setWidth(float width)
 +  {
 +    width_ = width;
 +  }
 +
 +  /**
 +   * @return Returns the maxCols.
 +   */
 +  public int getMaxCols()
 +  {
 +    return maxCols_;
 +  }
 +
 +  /**
 +   * @return Returns the name.
 +   */
 +  public String getName()
 +  {
 +    return name_;
 +  }
 +
 +  /**
 +   * This method returns a sorted row list beginning with the row number 1. The
 +   * entrys in a row also stored in a <code>{@link java.util.ArrayList}</code>.
 +   * 
 +   * @return Returns the sorted (by row number) table rows.
 +   */
 +  public ArrayList getRows()
 +  {
 +    ArrayList rows = new ArrayList();
 +    for (int row_idx = 1; row_idx <= rows_.size(); row_idx++)
 +    {
 +      ArrayList row = (ArrayList) rows_.get("" + row_idx);
 +      rows.add(row);
 +    }
 +    return rows;
 +  }
 +
 +  /**
 +   * Add a comlete table row to the current table. Be carefull usding the
 +   * correct row number because no check is done if a row with the given row
 +   * number does exist! In that case the stored row would be replaced!
 +   * 
 +   * @param rowNumber
 +   *          the row number to store the row entries
 +   * @param row
 +   *          the entry list to store
 +   */
 +  public void addRow(String rowNumber, ArrayList row)
 +  {
 +    rows_.put(rowNumber, row);
 +    if (row.size() > maxCols_)
 +    {
 +      maxCols_ = row.size();
 +    }
 +  }
 +
 +  /**
 +   * The toString method, used for tests or debugging.
 +   */
 +  public String toString()
 +  {
 +    String the_string = "\n#### TABLE " + name_ + " BEGIN #####";
 +    the_string += " Width:" + width_ + " max cols:" + maxCols_ + " cols:" + colsRelativeWith_;
 +    the_string += "\nStyle:" + style_;
 +    ArrayList rows = getRows();
 +    for (int row_idx = 0; row_idx < rows.size(); row_idx++)
 +    {
 +      ArrayList row = (ArrayList) rows.get(row_idx);
 +      String row_prefix = "\n ++ ROW " + row_idx + " ++ ";
 +      for (int entry_idx = 0; entry_idx < row.size(); entry_idx++)
 +      {
 +        the_string += row_prefix + ((Entry) row.get(entry_idx)).toString();
 +      }
 +    }
 +    the_string += "\n#### TABLE " + name_ + " END #####";
 +    return the_string;
 +  }
 +}
\ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e9bc3cf7..f439cf3c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include "signature-standards:sigs-pades", "pdf-as-lib" +include "pdf-as-common", "stamper:stmp-itext", "signature-standards:sigs-pades", "pdf-as-lib", "pdf-as-cli" diff --git a/signature-standards/sigs-pades/build.gradle b/signature-standards/sigs-pades/build.gradle index 4aee14ee..58151a7e 100644 --- a/signature-standards/sigs-pades/build.gradle +++ b/signature-standards/sigs-pades/build.gradle @@ -13,6 +13,7 @@ repositories {  dependencies {  	compile project (':pdf-as-lib') +	compile project (':pdf-as-common')      compile group: 'commons-collections', name: 'commons-collections', version: '3.2'      testCompile group: 'junit', name: 'junit', version: '4.+'  } diff --git a/stamper/stmp-itext/.gitignore b/stamper/stmp-itext/.gitignore new file mode 100644 index 00000000..5e56e040 --- /dev/null +++ b/stamper/stmp-itext/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/stamper/stmp-itext/build.gradle b/stamper/stmp-itext/build.gradle new file mode 100644 index 00000000..1495d8af --- /dev/null +++ b/stamper/stmp-itext/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'java' +apply plugin: 'eclipse' + +jar { +    manifest { +        attributes 'Implementation-Title': 'PDF-AS Stamper with itext', 'Implementation-Version': version +    } +} + +repositories { +    mavenCentral() +} + +dependencies { +	compile project (':pdf-as-lib') +	compile project (':pdf-as-common') +    compile group: 'commons-collections', name: 'commons-collections', version: '3.2' +	compile group: 'com.lowagie', name: 'itext', version: '4.2.0' +    testCompile group: 'junit', name: 'junit', version: '4.+' +} + +test { +    systemProperties 'property': 'value' +} + +uploadArchives { +    repositories { +       flatDir { +           dirs 'repos' +       } +    } +} diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java new file mode 100644 index 00000000..5c0fb7df --- /dev/null +++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java @@ -0,0 +1,506 @@ +package at.gv.egiz.pdfas.stmp.itext; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper; +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; +import at.gv.egiz.pdfas.lib.impl.status.PDFObject; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.table.Entry; +import at.knowcenter.wag.egov.egiz.table.Style; +import at.knowcenter.wag.egov.egiz.table.Table; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.HashMap; + +public class ITextStamper implements IPDFStamper { + +    private static final Logger logger = LoggerFactory.getLogger(ITextStamper.class); + +    /** +     * The default font definition +     */ +    private static Font DEFAULT_FONT = new Font(Font.HELVETICA, 8, Font.NORMAL); + +    private ISettings settings; +     +    /** +     * This method visualize an abstract table into a corresponding pdf table. The +     * new pdf table is redered and get the style information from the abstract +     * cell. +     * +     * @param abstractTable +     *          the abstract table definition +     * @return the new redererd pdf table cell +     * @throws PdfAsException +     *           ErrorCode:220, 221, 222, 223 +     * @see com.lowagie.text.pdf.PdfPTable +     * @see at.knowcenter.wag.egov.egiz.table.Table +     */ +    private PdfPTable renderTable(Table abstractTable) throws PdfAsException +    { +        if (abstractTable == null) +        { +            PdfAsException pde = new PdfAsException("Table is not defined."); +            throw pde; +        } +        PdfPTable pdf_table = null; +        float[] cols = abstractTable.getColsRelativeWith(); +        int max_cols = abstractTable.getMaxCols(); +        if (cols == null) +        { +            cols = new float[max_cols]; +            // set the column ratio for all columns to 1 +            for (int cols_idx = 0; cols_idx < cols.length; cols_idx++) +            { +                cols[cols_idx] = 1; +            } +        } +        pdf_table = new PdfPTable(cols); +        pdf_table.setWidthPercentage(abstractTable.getWidth()); +        Style table_style = abstractTable.getStyle(); +        setCellStyle(pdf_table.getDefaultCell(), table_style, Entry.TYPE_TABLE); + +        ArrayList rows = abstractTable.getRows(); +        for (int row_idx = 0; row_idx < rows.size(); row_idx++) +        { +            ArrayList row = (ArrayList) rows.get(row_idx); +            logger.debug("## Row:" + row_idx + " ## of table:" + abstractTable.getName()); +            for (int entry_idx = 0; entry_idx < row.size(); entry_idx++) +            { +                Entry cell = (Entry) row.get(entry_idx); +                // 03.11.2010 changed by exthex - swapped the two params, was probably a bug +                Style inherit_style = Style.doInherit(table_style, cell.getStyle()); +                cell.setStyle(inherit_style); +                logger.debug(cell.toString()); +                PdfPCell pdf_cell = renderCell(cell); +                if (cell.getColSpan() > 1) +                { +                    pdf_cell.setColspan(cell.getColSpan()); +                } +                if (cell.isNoWrap()) +                { +                    pdf_cell.setNoWrap(true); +                } +                // System.err.println("valign:" + pdf_cell.getVerticalAlignment() + " +                // halign:" + +                // pdf_cell.getHorizontalAlignment()); +                pdf_table.addCell(pdf_cell); +            } +            pdf_table.completeRow(); +        } +        logger.debug("render table:" + abstractTable.getName()); +        return pdf_table; +    } + +    /** +     * Map the style align definitions to IText's align statements +     */ +    private static HashMap<String, Integer> alignMap_ = new HashMap<String, Integer>(); + +    /** +     * Map the font definitions to IText's font statements +     */ +    private static HashMap<String, Integer> fontMap_ = new HashMap<String, Integer>(); + +    static  { +        initStyleMaps(); +    } + +    /** +     * This method initialize the style maps. It maps the style style definitions +     * to IText styles. +     */ +    private static void initStyleMaps() +    { +        alignMap_.put(Style.TOP, new Integer(Element.ALIGN_TOP)); +        alignMap_.put(Style.MIDDLE, new Integer(Element.ALIGN_MIDDLE)); +        alignMap_.put(Style.BOTTOM, new Integer(Element.ALIGN_BOTTOM)); +        alignMap_.put(Style.LEFT, new Integer(Element.ALIGN_LEFT)); +        alignMap_.put(Style.CENTER, new Integer(Element.ALIGN_CENTER)); +        alignMap_.put(Style.RIGHT, new Integer(Element.ALIGN_RIGHT)); + +        fontMap_.put(Style.HELVETICA, new Integer(Font.HELVETICA)); +        fontMap_.put(Style.TIMES_ROMAN, new Integer(Font.TIMES_ROMAN)); +        fontMap_.put(Style.COURIER, new Integer(Font.COURIER)); +        fontMap_.put(Style.NORMAL, new Integer(Font.NORMAL)); +        fontMap_.put(Style.BOLD, new Integer(Font.BOLD)); +        fontMap_.put(Style.ITALIC, new Integer(Font.ITALIC)); +        fontMap_.put(Style.BOLDITALIC, new Integer(Font.BOLDITALIC)); +        fontMap_.put(Style.UNDERLINE, new Integer(Font.UNDERLINE)); +        fontMap_.put(Style.STRIKETHRU, new Integer(Font.STRIKETHRU)); +    } + +    /** +     * This method maps the table cell definitions to the pdfCell element. +     * +     * @param pdfCell +     *          the pdf cell to be styled +     * @param cellStyle +     *          the abstract style definition +     * @param type +     *          type of the cell to render - the appropriate style will be set +     * @see com.lowagie.text.pdf.PdfPCell +     * @see at.knowcenter.wag.egov.egiz.table.Style +     */ +    private void setCellStyle(PdfPCell pdfCell, Style cellStyle, int type) +    { +        if (cellStyle != null) +        { +            if (cellStyle.getBgColor() != null) +            { +                pdfCell.setBackgroundColor(cellStyle.getBgColor()); +            } +            pdfCell.setPadding(cellStyle.getPadding()); +            //exthex - fix for not exactly vertically centered text +            pdfCell.setUseAscender(true); + +            if (cellStyle.getBorder() > 0) +            { +                pdfCell.setBorderWidth(cellStyle.getBorder()); +            } +            else +            { +                pdfCell.setBorder(0); +            } +            int align = -1; +            if (type == Entry.TYPE_VALUE && cellStyle.getValueVAlign() != null) +                align = ((Integer) alignMap_.get(cellStyle.getValueVAlign())).intValue(); +                //Note: to change the default valign of images to those of values, change the if construct below +            else if (type == Entry.TYPE_IMAGE && cellStyle.getImageVAlign() != null) +                align = ((Integer) alignMap_.get(cellStyle.getImageVAlign())).intValue(); +            else if (cellStyle.getVAlign() != null) + +                if(alignMap_.get(cellStyle.getVAlign()) == null) { +                    align = -1; +                } else { +                    align = alignMap_.get(cellStyle.getVAlign()).intValue(); +                } +            if (align != -1) +                pdfCell.setVerticalAlignment(align); + +            align = -1; +            if (type == Entry.TYPE_VALUE && cellStyle.getValueHAlign() != null) +                align = ((Integer) alignMap_.get(cellStyle.getValueHAlign())).intValue(); +                //Note: to change the default halign of images to those of values, change the if construct below +            else if (type == Entry.TYPE_IMAGE && cellStyle.getImageHAlign() != null) +                align = ((Integer) alignMap_.get(cellStyle.getImageHAlign())).intValue(); +            else if (cellStyle.getHAlign() != null) +                align = ((Integer) alignMap_.get(cellStyle.getHAlign())).intValue(); +            if (align != -1) +                pdfCell.setHorizontalAlignment(align); +        } +    } + +    /** +     * Creates a custom +     * @param fontString +     * @return +     * @throws PdfAsException +     */ +    private Font getCellTrueTypeFont(String fontString) throws PdfAsException { +        float fontSize=8; +        String fontName = fontString.replaceFirst("TTF:", ""); +        String[] split = fontName.split(","); +        if(split.length>1) +        { +            fontName = split[0].trim(); +            try +            { +                fontSize = Float.parseFloat(split[1].trim()); +            }catch (NumberFormatException e) +            { +                logger.error("Unable to parse fontsize:"+fontString); +            } +        } +        logger.debug("TrueType Font detected:"+fontName +" ("+fontSize+")"); + +        //try { + +            Font font = new Font(fontMap_.get(fontString)); +            //Font font = (Font) fontMap_.get(fontString); + +            // TODO: implement FONT resources via settings path! +            /*if (font == null) { +                logger.debug("Font \"" + fontString + "\" not in cache. Instantiating font."); +                String fontPath = SettingsReader.RESOURCES_PATH + "fonts" + File.separator + fontName; +                logger.debug("Instantiating \"" + fontPath + "\"."); + +                font = new Font(BaseFont.createFont(fontPath, BaseFont.WINANSI, true), fontSize); +                fontMap_.put(fontString, font); +            }       */ +            return font; +       // } catch (DocumentException e) { +        //    throw new PdfAsException(e.getMessage()); +        //} catch (IOException e) { +        //    throw new PdfAsException(e.getMessage()); +        //} +    } + + +    /** +     * This method maps the cell font definition to the iText Font Object +     * +     * @param fontString +     * @return the corresponding iText Font Object +     * @see com.lowagie.text.Font +     */ +    private Font getCellFont(String fontString) +    { +        Font font = DEFAULT_FONT; +        if (fontString == null) +        { +            return font; +        } +        Object cache_font = fontMap_.get(fontString); +        if (cache_font != null) +        { +            return (Font) cache_font; +        } +        String[] font_arr = fontString.split(","); +        if (font_arr.length != 3) +        { +            return font; +        } +        Object font_face = fontMap_.get(font_arr[0]); +        if (font_face == null) +        { +            return font; +        } +        Object font_weight = fontMap_.get(font_arr[2]); +        if (font_weight == null) +        { +            return font; +        } +        int face = ((Integer) font_face).intValue(); +        float height = Float.parseFloat(font_arr[1]); +        int weight = ((Integer) font_weight).intValue(); + +        font = new Font(face, height, weight); +        //fontMap_.put(fontString, font); +        return font; +    } + +    /** +     * This method visualize an abstract table cell into a corresponding pdf table +     * cell. The new pdf table cell is redered and get the style information from +     * the abstract cell. Following types can be rendered: +     * <ul> +     * <li>text statements</li> +     * <li>images</li> +     * <li>tables</li> +     * </ul> +     * +     * @param abstractCell +     *          the abstract cell definition +     * @return the new redererd pdf table cell +     * @throws PdfAsException +     *           ErrorCode:220, 221, 222 +     * @see com.lowagie.text.pdf.PdfPCell +     * @see at.knowcenter.wag.egov.egiz.table.Entry +     */ +    private PdfPCell renderCell(Entry abstractCell) throws PdfAsException +    { +        // TODO: read if signature should be PDF/A compatible!! +        boolean pdfaValid = false;//PDFASUtils.isPdfAEnabled(sigObject_.getSignatureTypeDefinition().getType()); + +        PdfPCell pdf_cell = null; +        Style cell_style = abstractCell.getStyle(); +        boolean isValue = true; +        switch (abstractCell.getType()) +        { +            case Entry.TYPE_CAPTION: +                isValue = false; +            case Entry.TYPE_VALUE: +                String text = (String) abstractCell.getValue(); +                if (text == null) +                { +                    text = ""; +                } +                String font_string = cell_style.getFont(); +                if (abstractCell.getType() == Entry.TYPE_VALUE && cell_style.getValueFont() != null) +                { +                    font_string = cell_style.getValueFont(); +                } + +                logger.trace("using cell font: "+font_string); + +                Font cell_font; +                if(font_string.startsWith("TTF:")) +                { +                    cell_font = getCellTrueTypeFont(font_string); +                } +                else +                { +                    if (pdfaValid) { +                        throw new PdfAsException("PDF/A modus requires an embedable true type font"); +                    } +                    cell_font = getCellFont(font_string); + +                } +                //TODO: check and maybe remove ... +                // exthex +                //if (pdfaValid && abstractCell.getType() == Entry.TYPE_VALUE) { +                //    SubsetLocal.addNonSubsetFont(cell_font.getBaseFont()); +                //} +                Phrase text_phrase = new Phrase(text, cell_font); +                pdf_cell = new PdfPCell(text_phrase); +                setCellStyle(pdf_cell, cell_style, (isValue?Entry.TYPE_VALUE:Entry.TYPE_CAPTION)); +                break; +            case Entry.TYPE_IMAGE: +                try +                { +                    String img_ref = (String) abstractCell.getValue(); +                    // fixed by tknall start +                    File img_file = new File(img_ref); +                    if (!img_file.isAbsolute()) { +                        logger.debug("Image file declaration is relative. Prepending path of resources directory."); +                        //TODO: implement settings .... +                        img_file = new File(settings.getWorkingDirectory() + File.separator + img_ref); +                    } else { +                        logger.debug("Image file declaration is absolute. Skipping file relocation."); +                    } +//        String img_location = SettingsReader.relocateFile(img_ref); +//        File img_file = new File (img_location); +                    if (!img_file.exists()) +                    { +                        logger.debug("Image file \"" + img_file.getCanonicalPath() + "\" doesn't exist."); +                        throw new PdfAsException("Image file \"" + img_file.getCanonicalPath() + "\" doesn't exist."); +                    } +                    Image image = Image.getInstance(img_file.getCanonicalPath()); +                    logger.debug("Using image file \"" + img_file.getCanonicalPath() + "\"."); + +                    image.scaleToFit(80.0f, 80.0f); +                    boolean fit = true; +                    Style.ImageScaleToFit istf = cell_style.getImageScaleToFit(); +                    if (istf != null) +                    { +                        image.scaleToFit(istf.getWidth(), istf.getHeight()); +                        fit = false; +                    } +                    pdf_cell = new PdfPCell(image, fit); +                    setCellStyle(pdf_cell, cell_style, Entry.TYPE_IMAGE); +                } +                catch (BadElementException e) +                { +                    logger.error("BadElementException:" + e.getMessage()); +                    PdfAsException pde = new PdfAsException("Unable to create PDF table."); +                    throw pde; +                } +                catch (MalformedURLException e) +                { +                    logger.error("MalformedURLException:" + e.getMessage()); +                    PdfAsException pde = new PdfAsException("Unable to create PDF table."); +                    throw pde; +                } +                catch (IOException e) +                { +                    logger.error("Error Code: 222, IOException:" + e.getMessage()); +                    PdfAsException pde = new PdfAsException("Unable to create PDF table, unable to load image."); +                    throw pde; +                } +                break; +            case Entry.TYPE_TABLE: +                Table table = (Table) abstractCell.getValue(); +                // inherit the style from the parent table +                Style inherit_style = Style.doInherit(table.getStyle(), cell_style); +                table.setStyle(inherit_style); +                PdfPTable pdf_table = renderTable(table); +                pdf_cell = new PdfPCell(pdf_table); +                // The default new PdfPCell has a default border of 15. +                // For blocks without border and subtables this results +                // in a border to be drawn around the cell. +                // ==> no border on default +                pdf_cell.setBorder(0); +                break; +        } +        return pdf_cell; +    } + +    public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table) { + +        // TODO: Adapt PDFSignatureObjectIText to render PDFPTable to iTextVisualObject from table +        try { +        PdfPTable pdfPTable = renderTable(table); + +        ITextVisualObject iTextVisualObject = new ITextVisualObject(pdfPTable); + +        return iTextVisualObject; +        } catch (PdfAsException e) { +            e.printStackTrace(); +            return null; +        } +    } + +    public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction, +                                    byte[] pdfData) throws PdfAsException { +        try { + +            ITextVisualObject object = null; +            if(visualObject instanceof  ITextVisualObject)      { +                object = (ITextVisualObject)visualObject; +            } + +            if(object == null) { +                //TODO: exception! +                return null; +            } + +            PdfReader reader = new PdfReader(pdfData); + +            ByteArrayOutputStream baos = new ByteArrayOutputStream(); + +            PdfStamper stamper = new PdfStamper(reader, baos, reader.getPdfVersion(), true); + +            int pages = reader.getNumberOfPages(); +            int targetPage = positioningInstruction.getPage(); + +            // TODO: maybe add new page ... +            if(positioningInstruction.isMakeNewPage()) { +                Rectangle rect = reader.getPageSize(pages); +                stamper.insertPage(pages + 1, new Rectangle(rect)); +                targetPage = pages + 1; +            } + +            if (positioningInstruction.getPage() < 1 || +                    positioningInstruction.getPage() > stamper.getReader().getNumberOfPages()) +            { +                throw new PdfAsException("The provided page (=" + +                        positioningInstruction.getPage() + ") is out of range."); +            } + +            PdfContentByte content = stamper.getOverContent(targetPage); + +            PdfPTable table = object.getTable(); + +            table.writeSelectedRows(0, -1, positioningInstruction.getX(), +                    positioningInstruction.getY(), content); + +            stamper.close(); + +            baos.close(); + +            return baos.toByteArray(); + +        } catch (IOException e) { +            logger.error(e.getMessage(), e); +        } catch (DocumentException e) { +            logger.error(e.getMessage(), e); +        } +        return null; +    } + +	public void setSettings(ISettings settings) { +		this.settings = settings; +	} +}
\ No newline at end of file diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java new file mode 100644 index 00000000..76b8b0fc --- /dev/null +++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java @@ -0,0 +1,61 @@ +package at.gv.egiz.pdfas.stmp.itext; + +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; +import at.knowcenter.wag.egov.egiz.pdf.Pos; +import com.lowagie.text.pdf.PdfPTable; + +public class ITextVisualObject implements IPDFVisualObject { + +    private PdfPTable table; +    private float x; +    private float y; +    private int page; + +    public  ITextVisualObject(PdfPTable table) { +        this.table = table; +    } + +    public void setWidth(float width) { +        table.setTotalWidth(width); +    } + +    public void fixWidth() { +        table.setLockedWidth(true); +    } + +    public float getHeight() { +        return this.table.getTotalHeight(); +    } + +    public float getWidth() { +        return this.table.getTotalWidth(); +    } + +    public void setXPos(float x) { +        this.x = x; +    } + +    public void setYPos(float y) { +        this.y = y; +    } + +    public float getX() { +        return x; +    } + +    public float getY() { +        return y; +    } + +    public int getPage() { +        return page; +    } + +    public void setPage(int page) { +        this.page = page; +    } + +    public PdfPTable getTable() { +        return table; +    } +} diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java new file mode 100644 index 00000000..53f799b4 --- /dev/null +++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java @@ -0,0 +1,2 @@ + +package at.gv.egiz.pdfas.stmp.itext;
\ No newline at end of file | 
