]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/ExportPdfFormat.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.export.core / src / org / simantics / export / core / pdf / ExportPdfFormat.java
diff --git a/bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/ExportPdfFormat.java b/bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/ExportPdfFormat.java
new file mode 100644 (file)
index 0000000..1f2667d
--- /dev/null
@@ -0,0 +1,595 @@
+package org.simantics.export.core.pdf;\r
+\r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.StringTokenizer;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+import java.util.regex.Pattern;\r
+\r
+import org.eclipse.core.runtime.IProduct;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.preferences.DefaultScope;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.osgi.service.prefs.Preferences;\r
+import org.simantics.databoard.Accessors;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.accessor.RecordAccessor;\r
+import org.simantics.databoard.accessor.UnionAccessor;\r
+import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
+import org.simantics.databoard.accessor.error.AccessorException;\r
+import org.simantics.databoard.accessor.error.ReferenceException;\r
+import org.simantics.databoard.accessor.reference.ChildReference;\r
+import org.simantics.databoard.accessor.reference.LabelReference;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.forms.DataboardForm;\r
+import org.simantics.databoard.type.DoubleType;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.databoard.type.StringType;\r
+import org.simantics.databoard.type.UnionType;\r
+import org.simantics.export.core.ExportContext;\r
+import org.simantics.export.core.error.ExportException;\r
+import org.simantics.export.core.intf.FormatClass;\r
+import org.simantics.export.core.manager.Content;\r
+import org.simantics.export.core.util.ExporterUtils;\r
+import org.simantics.utils.page.MarginUtils;\r
+import org.simantics.utils.page.MarginUtils.Margin;\r
+import org.simantics.utils.page.MarginUtils.Margins;\r
+import org.simantics.utils.page.PageDesc;\r
+import org.simantics.utils.page.PageOrientation;\r
+\r
+import com.lowagie.text.Document;\r
+import com.lowagie.text.DocumentException;\r
+import com.lowagie.text.FontFactory;\r
+import com.lowagie.text.Rectangle;\r
+import com.lowagie.text.pdf.DefaultFontMapper;\r
+import com.lowagie.text.pdf.PdfBoolean;\r
+import com.lowagie.text.pdf.PdfCopy;\r
+import com.lowagie.text.pdf.PdfName;\r
+import com.lowagie.text.pdf.PdfWriter;\r
+\r
+/**\r
+ * Represents the actions to Pdf File format in Export Core.\r
+ *\r
+ * @author toni.kalajainen@semantum.fi\r
+ */\r
+public class ExportPdfFormat implements FormatClass {\r
+\r
+       public static final Pattern PATTERN_PDF = Pattern.compile(".*\\.pdf$", Pattern.CASE_INSENSITIVE);\r
+       \r
+       // Options references\r
+       public static String S_PDF = "Portable Document Format (PDF)";\r
+       public static ChildReference P_PDF_TITLE = ChildReference.parsePath(S_PDF+"/Title");\r
+       public static ChildReference P_PDF_AUTHOR = ChildReference.parsePath(S_PDF+"/Author");\r
+       public static ChildReference P_PDF_SUBJECT = ChildReference.parsePath(S_PDF+"/Subject");\r
+       public static ChildReference P_PDF_KEYWORDS = ChildReference.parsePath(S_PDF+"/Keywords");\r
+       public static ChildReference P_PDF_COMPRESSION = ChildReference.parsePath(S_PDF+"/Compression");\r
+       \r
+       public static String S_SIGN = "Digital Signature";\r
+       public static LabelReference P_SIGN = new LabelReference( S_SIGN );\r
+       public static ChildReference P_SIGN_KEYSTORE = ChildReference.concatenate(P_SIGN, new LabelReference("Keystore") );     \r
+       public static ChildReference P_SIGN_KEYSTOREPASSWORD = ChildReference.concatenate(P_SIGN, new LabelReference("Keystore Password"));\r
+       public static ChildReference P_SIGN_PRIVATEKEYPASSWORD = ChildReference.concatenate(P_SIGN, new LabelReference("Private Key Password"));\r
+       public static ChildReference P_SIGN_LOCATION = ChildReference.concatenate(P_SIGN, new LabelReference("Sign Location")); \r
+       public static ChildReference P_SIGN_REASON = ChildReference.concatenate(P_SIGN, new LabelReference("Sign Reason"));     \r
+\r
+       public static String S_PAGE = "Page Settings";\r
+       public static ChildReference P_PAGE = new LabelReference( S_PAGE );\r
+       public static ChildReference P_PAGE_PAPERSIZE = ChildReference.concatenate(P_PAGE, new LabelReference("Size"));\r
+       public static ChildReference P_PAGE_ORIENTATION = ChildReference.concatenate(P_PAGE, new LabelReference("Orientation"));\r
+       public static ChildReference P_PAGE_MARGIN_LEFT = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Left"));\r
+       public static ChildReference P_PAGE_MARGIN_RIGHT = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Right"));\r
+       public static ChildReference P_PAGE_MARGIN_TOP = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Top"));\r
+       public static ChildReference P_PAGE_MARGIN_BOTTOM = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Bottom"));\r
+       \r
+       // Preference page IDs\r
+    public static String PAGE_PLUGIN_ID = "org.simantics.modeling.ui";\r
+       \r
+    public static String P_DEFAULT_PAGE_SIZE        = "page.default.size";\r
+    \r
+    private static final AtomicBoolean fontFactoryInitialized = new AtomicBoolean();\r
+    \r
+    public static final RecordType pdfOptions;\r
+\r
+    static {\r
+       pdfOptions = new RecordType();          \r
+       DoubleType mm = new DoubleType();\r
+       mm.setUnit("mm");\r
+       \r
+           // PDF metadata         \r
+       RecordType pdfRecord = new RecordType();\r
+           pdfRecord.addComponent("Title", Datatypes.STRING );\r
+           pdfRecord.addComponent("Author", Datatypes.STRING );\r
+           pdfRecord.addComponent("Subject", Datatypes.STRING );\r
+           pdfRecord.addComponent("Keywords", DataboardForm.TEXTBOX );     \r
+           // Formatter options \r
+           pdfRecord.addComponent("Compression", UnionType.newEnum("0 (No compression)", "1", "2", "3", "4", "5", "6", "7", "8", "9 (Best)"));\r
+           \r
+           // PDF Encryption\r
+       RecordType pdfSign = new RecordType();\r
+           StringType certificate = DataboardForm.fileOpenDialog("PKCS#12 keystore (.p12)", "*.p12", "PFX (.pfx)", "*.pfx"); //, "Privacy Enhanced Mail (.pem)", ".pem" \r
+           pdfSign.addComponent("Keystore", certificate);\r
+           pdfSign.addComponent("Keystore Password", DataboardForm.PASSWORD);\r
+           pdfSign.addComponent("Private Key Password", DataboardForm.PASSWORD);\r
+           pdfSign.addComponent("Sign Location", Datatypes.STRING);        \r
+           pdfSign.addComponent("Sign Reason", Datatypes.STRING);                  \r
+           \r
+           PageDesc[] descs = PageDesc.PDF_ITEMS;\r
+           String[] pageSizesStr = new String[ descs.length ];\r
+           for ( int i=0; i<descs.length; i++ ) pageSizesStr[i] = descs[i].getText();\r
+           UnionType pageSizes = UnionType.newEnum("A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10");\r
+           UnionType orientation = UnionType.newEnum("Portrait", "Landscape");\r
+           RecordType pagePrefs = new RecordType();\r
+           pagePrefs.addComponent("Size", pageSizes);\r
+           pagePrefs.addComponent("Orientation", orientation);\r
+           pagePrefs.addComponent("Margin Left", mm);\r
+           pagePrefs.addComponent("Margin Right", mm);\r
+           pagePrefs.addComponent("Margin Top", mm);\r
+           pagePrefs.addComponent("Margin Bottom", mm);\r
+           //pagePrefs.metadata.put("style", "dialog");\r
+           \r
+           pdfOptions.addComponent(S_PDF, pdfRecord);\r
+           pdfOptions.addComponent(S_SIGN, pdfSign);\r
+           pdfOptions.addComponent(S_PAGE, pagePrefs);\r
+    }\r
+    \r
+       @Override\r
+       public RecordType options(ExportContext context) throws ExportException {\r
+               return pdfOptions;              \r
+       }\r
+\r
+       @Override\r
+       public Object createFile(ExportContext ctx, File outputFile, Variant options) throws ExportException {\r
+               try {\r
+                       RecordAccessor ra = Accessors.getAccessor( options );\r
+                       \r
+            if (fontFactoryInitialized.compareAndSet(false, true)) {\r
+                // Only register directories once.\r
+                FontFactory.registerDirectories();\r
+            }\r
+            \r
+                       ExportPdfWriter writer = new ExportPdfWriter();\r
+                       \r
+                       Rectangle pageSize = null;\r
+                       writer.document = new Document(pageSize);\r
+                       writer.outputFile = outputFile;\r
+                       writer.fos = new FileOutputStream(writer.outputFile);\r
+                       writer.pdfCopy = new PdfCopy(writer.document, writer.fos); \r
+                       writer.pdfCopy.setPdfVersion(PdfWriter.PDF_VERSION_1_7);\r
+                       writer.fontMapper = new DefaultFontMapper();\r
+                       writer.options = options;\r
+                       writer.ctx = ctx;\r
+\r
+                       String creator = getCreator();\r
+                       writer.document.addCreator(creator);\r
+\r
+                       String s; \r
+                       s = (String) ra.getValue(P_PDF_TITLE, Bindings.STRING);\r
+                       if ( s!=null ) writer.document.addTitle(s);                     \r
+\r
+                       s = (String) ra.getValue(P_PDF_AUTHOR, Bindings.STRING);\r
+                       if ( s!=null ) writer.document.addAuthor(s);\r
+\r
+                       s = (String) ra.getValue(P_PDF_SUBJECT, Bindings.STRING);\r
+                       if ( s!=null ) writer.document.addSubject(s);\r
+\r
+                       s = (String) ra.getValue(P_PDF_KEYWORDS, Bindings.STRING);\r
+                       if ( s!=null ) writer.document.addKeywords(s);\r
+\r
+                       // Compression Level\r
+                       try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PDF_COMPRESSION);\r
+                       int tag = ua.getTag();                  \r
+                       writer.pdfCopy.setCompressionLevel( tag );\r
+                       writer.compressionLevel = tag;\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+\r
+                       // PageSize\r
+                       {                               \r
+                               Margins margins = MarginUtils.MARGINS_10mm;\r
+                               Double left = (Double) ra.getValue(P_PAGE_MARGIN_LEFT, Bindings.DOUBLE);\r
+                               if ( left!=null ) margins = margins.withSide(Margins.LEFT, new Margin(0, 0, left));\r
+                               Double right = (Double) ra.getValue(P_PAGE_MARGIN_RIGHT, Bindings.DOUBLE);\r
+                               if ( right!=null ) margins = margins.withSide(Margins.RIGHT, new Margin(0, 0, right));\r
+                               Double bottom = (Double) ra.getValue(P_PAGE_MARGIN_BOTTOM, Bindings.DOUBLE);\r
+                               if ( bottom!=null ) margins = margins.withSide(Margins.BOTTOM, new Margin(0, 0, bottom));\r
+                               Double top = (Double) ra.getValue(P_PAGE_MARGIN_TOP, Bindings.DOUBLE);\r
+                               if ( top!=null ) margins = margins.withSide(Margins.TOP, new Margin(0, 0, top));\r
+                               \r
+                               String paperName = "A4";\r
+                               try {                   \r
+                               UnionAccessor ua = ra.getComponent(P_PAGE_PAPERSIZE);\r
+                               int tag = ua.getTag();\r
+                               paperName = ua.type().getComponent(tag).name;                           \r
+                       } catch (ReferenceException re) {                       \r
+                               }\r
+                               \r
+                               PageOrientation pageOrientation = PageOrientation.Portrait;\r
+                               try {                   \r
+                               UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);\r
+                               int tag = ua.getTag();\r
+                               String str = ua.type().getComponent(tag).name;\r
+                               pageOrientation = PageOrientation.valueOf( str );\r
+                       } catch (ReferenceException re) {                       \r
+                               }\r
+                               \r
+                               PageDesc pd = PageDesc.getByName(paperName);\r
+                               pd = pd.withOrientation(pageOrientation);\r
+                               pd = pd.withMargins(margins);\r
+                               writer.margins = margins;\r
+                               writer.defaultPageDesc = pd;\r
+                               writer.defaultRectangle = ExportPdfWriter.toRectangle( writer.defaultPageDesc );\r
+                               writer.document.setPageSize( writer.defaultRectangle );\r
+                       }\r
+                       \r
+                       // Add Developer Extension - not used\r
+//             PdfName companyName = new PdfName("SMTC");          \r
+//         PdfDeveloperExtension ext = new PdfDeveloperExtension(companyName, PdfWriter.PDF_VERSION_1_7, 3);\r
+//         writer.addDeveloperExtension( ext );\r
+                       \r
+                       \r
+            writer.document.open();\r
+            writer.cb = writer.pdfCopy.getDirectContent();\r
+                       \r
+                       return writer;\r
+               } catch (FileNotFoundException e) {\r
+                       throw new ExportException( e );\r
+               } catch (DocumentException e) {\r
+                       throw new ExportException( e );\r
+               } catch (AccessorConstructionException e) {\r
+                       throw new ExportException( e );\r
+               } catch (AccessorException e) {\r
+                       throw new ExportException( e );\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public Object openFile(ExportContext context, File inputFile, Variant options) throws ExportException {\r
+               try {\r
+                       return new ImportPdfReader(inputFile);\r
+               } catch (IOException e) {\r
+                       throw new ExportException(e);\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public List<String> validate(ExportContext context, Variant options) throws ExportException {\r
+               List<String> problems = new ArrayList<String>();\r
+               \r
+               try {\r
+                       RecordAccessor ra = Accessors.getAccessor( options );\r
+\r
+                       // Assert the keystore file exists, if set.\r
+                       String keystoreFileName = (String) ra.getValue(P_SIGN_KEYSTORE, Bindings.STRING);                                                       \r
+                       if ( keystoreFileName != null && !keystoreFileName.isEmpty() ) {\r
+                               File keystoreFile = new File( keystoreFileName );\r
+                               if ( !keystoreFile.exists() ) {\r
+                                       problems.add( "Keystore file was not found: "+keystoreFile );\r
+                               }\r
+                       }\r
+                       \r
+               } catch (AccessorConstructionException e) {\r
+                       throw new ExportException( e );\r
+               } catch (AccessorException e) {\r
+                       throw new ExportException( e );\r
+               }\r
+               \r
+               return problems;\r
+       }\r
+\r
+       @Override\r
+       public void closeFile(ExportContext context, Object handle) throws ExportException {\r
+               if ( handle instanceof ImportPdfReader ) {\r
+                       ImportPdfReader reader = (ImportPdfReader) handle;\r
+                       reader.close();\r
+               }\r
+               \r
+               if ( handle instanceof ExportPdfWriter ) {\r
+                       ExportPdfWriter writer = (ExportPdfWriter) handle;\r
+       \r
+                       writer.close();\r
+                       \r
+                       try {\r
+                               RecordAccessor ra = Accessors.getAccessor( writer.options );\r
+                               \r
+                               String keystoreFileName = (String) ra.getValue(P_SIGN_KEYSTORE, Bindings.STRING);                               \r
+                               String keystorePassword = (String) ra.getValue(P_SIGN_KEYSTOREPASSWORD, Bindings.STRING);\r
+                               String privateKeyPassword = (String) ra.getValue(P_SIGN_PRIVATEKEYPASSWORD, Bindings.STRING);\r
+                               String signLocation = (String) ra.getValue(P_SIGN_LOCATION, Bindings.STRING);\r
+                               String signReason = (String) ra.getValue(P_SIGN_REASON, Bindings.STRING);\r
+                               \r
+                               if ( keystoreFileName != null && !keystoreFileName.isEmpty() ) \r
+                               {\r
+                                       File keystoreFile = new File( keystoreFileName );\r
+                                       if ( !keystoreFile.exists() ) {\r
+                                               throw new ExportException( "Keystore file was not found: "+keystoreFile );\r
+                                       }\r
+                                       writer.sign(keystoreFile, keystorePassword, privateKeyPassword, signLocation, signReason);\r
+                               }\r
+       \r
+                       } catch (AccessorConstructionException e) {\r
+                               throw new ExportException( e.getClass().getName()+": "+e.getMessage() );\r
+                       } catch (AccessorException e) {\r
+                               throw new ExportException( e.getClass().getName()+": "+e.getMessage() );\r
+                       }\r
+                       \r
+                       // Encrypt\r
+                   /*\r
+                   writer.setEncryption(\r
+                               new Certificate[] {}, \r
+                               new int[] {PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING}, \r
+                               PdfWriter.STANDARD_ENCRYPTION_128);\r
+                   //writer.setEncryption(PdfWriter.STANDARD_ENCRYPTION_128, "", "password", PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY);\r
+                       \r
+                       int permission = PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY;\r
+                       PdfEncryption crypto = new PdfEncryption();\r
+                       //for (Certificate c : chain) crypto.addRecipient(c, permission);\r
+                       //crypto.addRecipient(chain[2], permission);\r
+               crypto.setCryptoMode(PdfWriter.ENCRYPTION_AES_128, 0);\r
+                       crypto.setupByEncryptionKey(key.getEncoded(), key.getEncoded().length*8);\r
+               crypto.getEncryptionDictionary();\r
+                       */\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void addAttachment(ExportContext ctx, Object handle, List<Content> attachments) throws ExportException {\r
+               ExportPdfWriter writer = (ExportPdfWriter) handle; \r
+\r
+       writer.pdfCopy.addViewerPreference(PdfName.USEATTACHMENTS, PdfBoolean.PDFTRUE);\r
+               for ( Content content : attachments ) {\r
+                       writer.addAttachment( content );\r
+               }               \r
+       }\r
+       \r
+       @Override\r
+       public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {\r
+        try {\r
+                       RecordAccessor ra = Accessors.getAccessor(options);                     \r
+                       String s; \r
+                       \r
+                       s = (String) ra.getValue(P_PDF_TITLE, Bindings.STRING);\r
+                       if ( s!=null ) contentScopeNode.put(P_PDF_TITLE.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_PDF_AUTHOR, Bindings.STRING);\r
+                       if ( s!=null ) workbenchScopeNode.put(P_PDF_AUTHOR.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_PDF_SUBJECT, Bindings.STRING);\r
+                       if ( s!=null ) contentScopeNode.put(P_PDF_SUBJECT.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_PDF_KEYWORDS, Bindings.STRING);\r
+                       if ( s!=null ) contentScopeNode.put(P_PDF_KEYWORDS.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_SIGN_KEYSTORE, Bindings.STRING);\r
+                       if ( s!=null ) workbenchScopeNode.put(P_SIGN_KEYSTORE.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_SIGN_KEYSTOREPASSWORD, Bindings.STRING);\r
+                       if ( s!=null ) workbenchScopeNode.put(P_SIGN_KEYSTOREPASSWORD.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_SIGN_PRIVATEKEYPASSWORD, Bindings.STRING);\r
+                       if ( s!=null ) workbenchScopeNode.put(P_SIGN_PRIVATEKEYPASSWORD.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_SIGN_LOCATION, Bindings.STRING);\r
+                       if ( s!=null ) workbenchScopeNode.put(P_SIGN_LOCATION.tail().toString(), s);\r
+\r
+                       s = (String) ra.getValue(P_SIGN_REASON, Bindings.STRING);\r
+                       if ( s!=null ) workbenchScopeNode.put(P_SIGN_REASON.tail().toString(), s);\r
+                       \r
+                       try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PDF_COMPRESSION);\r
+                       int tag = ua.getTag();\r
+                       workbenchScopeNode.putInt(P_PDF_COMPRESSION.tail().toString(), tag);\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+                       \r
+                       Double d = (Double) ra.getValue(P_PAGE_MARGIN_LEFT, Bindings.DOUBLE);\r
+                       if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_LEFT.tail().toString(), d);\r
+\r
+                       d = (Double) ra.getValue(P_PAGE_MARGIN_RIGHT, Bindings.DOUBLE);\r
+                       if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_RIGHT.tail().toString(), d);\r
+                       \r
+                       d = (Double) ra.getValue(P_PAGE_MARGIN_BOTTOM, Bindings.DOUBLE);\r
+                       if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_BOTTOM.tail().toString(), d);\r
+\r
+                       d = (Double) ra.getValue(P_PAGE_MARGIN_TOP, Bindings.DOUBLE);\r
+                       if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_TOP.tail().toString(), d);\r
+                       \r
+                       try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PAGE_PAPERSIZE);\r
+                       int tag = ua.getTag();\r
+                       contentScopeNode.putInt(P_PAGE_PAPERSIZE.tail().toString(), tag);\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+                       \r
+                       try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);\r
+                       int tag = ua.getTag();\r
+                       contentScopeNode.putInt(P_PAGE_ORIENTATION.tail().toString(), tag);\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+                       \r
+               } catch (AccessorConstructionException e) {\r
+                       throw new ExportException(e);\r
+               } catch (AccessorException e) {\r
+                       throw new ExportException(e);\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {\r
+        try {\r
+                       RecordAccessor ra = Accessors.getAccessor(options);                     \r
+                       String s;\r
+                       \r
+                       s = contentScopeNode.get(P_PDF_TITLE.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PDF_TITLE, Bindings.STRING, s);\r
+               \r
+                       s = workbenchScopeNode.get(P_PDF_AUTHOR.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PDF_AUTHOR, Bindings.STRING, s);\r
+               \r
+                       s = contentScopeNode.get(P_PDF_SUBJECT.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PDF_SUBJECT, Bindings.STRING, s);\r
+               \r
+                       s = contentScopeNode.get(P_PDF_KEYWORDS.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PDF_KEYWORDS, Bindings.STRING, s);\r
+               \r
+                       s = workbenchScopeNode.get(P_SIGN_KEYSTORE.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_SIGN_KEYSTORE, Bindings.STRING, s);\r
+               \r
+                       s = workbenchScopeNode.get(P_SIGN_KEYSTOREPASSWORD.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_SIGN_KEYSTOREPASSWORD, Bindings.STRING, s);\r
+               \r
+                       s = workbenchScopeNode.get(P_SIGN_PRIVATEKEYPASSWORD.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_SIGN_PRIVATEKEYPASSWORD, Bindings.STRING, s);\r
+\r
+                       s = workbenchScopeNode.get(P_SIGN_LOCATION.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_SIGN_LOCATION, Bindings.STRING, s);\r
+                       \r
+                       s = workbenchScopeNode.get(P_SIGN_REASON.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_SIGN_REASON, Bindings.STRING, s);\r
+\r
+                       int tag = workbenchScopeNode.getInt(P_PDF_COMPRESSION.tail().toString(), -1);\r
+                       if ( tag>=0 )\r
+               try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PDF_COMPRESSION);\r
+                       ua.setComponentValue(tag, Bindings.VOID, null);\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+               \r
+               \r
+\r
+                       s = contentScopeNode.get(P_PAGE_MARGIN_LEFT.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PAGE_MARGIN_LEFT, Bindings.DOUBLE, Double.valueOf(s));\r
+               \r
+                       s = contentScopeNode.get(P_PAGE_MARGIN_RIGHT.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PAGE_MARGIN_RIGHT, Bindings.DOUBLE, Double.valueOf(s));\r
+               \r
+                       s = contentScopeNode.get(P_PAGE_MARGIN_TOP.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PAGE_MARGIN_TOP, Bindings.DOUBLE, Double.valueOf(s));\r
+               \r
+                       s = contentScopeNode.get(P_PAGE_MARGIN_BOTTOM.tail().toString(), null);\r
+                       if ( s!=null ) ra.setValue(P_PAGE_MARGIN_BOTTOM, Bindings.DOUBLE, Double.valueOf(s));\r
+                       \r
+                       tag = contentScopeNode.getInt(P_PAGE_PAPERSIZE.tail().toString(), -1);\r
+                       if ( tag>=0 )\r
+               try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PAGE_PAPERSIZE);\r
+                       ua.setComponentValue(tag, Bindings.VOID, null);\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+                       \r
+                       tag = contentScopeNode.getInt(P_PAGE_ORIENTATION.tail().toString(), -1);\r
+                       if ( tag>=0 )\r
+               try {                   \r
+                       UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);\r
+                       ua.setComponentValue(tag, Bindings.VOID, null);\r
+               } catch (ReferenceException re) {                       \r
+                       }\r
+               \r
+               \r
+               } catch (AccessorConstructionException e) {\r
+                       throw new ExportException(e);\r
+               } catch (AccessorException e) {\r
+                       throw new ExportException(e);\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void fillDefaultPrefs( ExportContext ctx, Variant options) throws ExportException {\r
+        try {\r
+                       RecordAccessor ra = Accessors.getAccessor(options);     \r
+\r
+                       Preferences instPrefs = InstanceScope.INSTANCE.getNode( PAGE_PLUGIN_ID );\r
+                       Preferences defaultPrefs = DefaultScope.INSTANCE.getNode( PAGE_PLUGIN_ID );\r
+                       \r
+                       String value = ExporterUtils.getPrefString(instPrefs, defaultPrefs, P_DEFAULT_PAGE_SIZE);\r
+               if ( value != null ) {\r
+                       try {\r
+                    StringTokenizer tok = new StringTokenizer( value );\r
+                    String w = tok.nextToken().trim();\r
+                    String h = tok.nextToken().trim();\r
+                    String orientation = tok.nextToken().trim();\r
+                    if ( orientation!=null ) {\r
+                               try {                                                           \r
+                               UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);\r
+                               int index = ua.type().getComponentIndex2(orientation);\r
+                               if ( index<0 ) index = 1;\r
+                               ua.setComponentValue(index, Bindings.VOID, new Object());\r
+                       } catch (ReferenceException re) {                                                                       \r
+                               }\r
+                    }\r
+                    String centering = tok.nextToken().trim();\r
+                    String pagesize = tok.nextToken("\u0001").trim();\r
+                    ExporterUtils.setUnionValue(ra, P_PAGE_PAPERSIZE, pagesize);\r
+                    \r
+                    String margins = tok.nextToken().trim();                               \r
+                    if ( margins != null ) {\r
+                        String[] split = margins.split(";");\r
+                        if (split.length == 4) {\r
+                               for (int i=0; i<4; i++) {\r
+                                       String[] tok2 = split[i].split(" ");\r
+                                       String controlRelative = tok2[0];\r
+                                       String controlAbsolute = tok2[1];\r
+                                       String diagramAbsolute = tok2[2];\r
+                                       \r
+                                       ChildReference ref = null;\r
+                                       switch (i) {\r
+                                               case 0: ref = P_PAGE_MARGIN_TOP; break;\r
+                                               case 1: ref = P_PAGE_MARGIN_BOTTOM; break;\r
+                                               case 2: ref = P_PAGE_MARGIN_LEFT; break;\r
+                                               case 3: ref = P_PAGE_MARGIN_RIGHT; break;\r
+                                       }\r
+                                       double margin_mm = Double.valueOf(diagramAbsolute);\r
+                                               ra.setValue(ref, Bindings.DOUBLE, margin_mm);                                                           \r
+                               }                                               \r
+                        }\r
+                    }\r
+                       } catch( Exception e ) {\r
+                               // This is not so important that pdf export should fail.\r
+                               e.printStackTrace();\r
+                       }\r
+\r
+               }\r
+                       \r
+               String username = System.getProperty("user.name");\r
+               if ( username != null ) ra.setValue(P_PDF_AUTHOR, Bindings.STRING, username);\r
+\r
+               ra.setValue(P_SIGN_REASON, Bindings.STRING, "Document Created");\r
+               ExporterUtils.setUnionValue(ra, P_PDF_COMPRESSION, 9);          \r
+               \r
+               } catch (AccessorConstructionException e) {\r
+                       throw new ExportException(e);\r
+               } catch (AccessorException e) {\r
+                       throw new ExportException(e);\r
+               }\r
+       }       \r
+\r
+       public static String getCreator() {\r
+               String creator = null;\r
+               IProduct product = Platform.getProduct();\r
+               if (product != null) {\r
+                       creator = product.getDescription();\r
+                       if (creator == null) {\r
+                               creator = product.getName();\r
+                       }\r
+               }\r
+               if (creator == null) {\r
+                       creator = "Simantics";\r
+               }\r
+               return creator;\r
+       }\r
+\r
+       public static boolean isPdf(String filename) {\r
+               return PATTERN_PDF.matcher(filename).matches();\r
+       }\r
+       \r
+       public static boolean isPdf(File file) {\r
+               return PATTERN_PDF.matcher(file.getName()).matches();\r
+       }\r
+       \r
+}\r