Java tutorial
/**************************************************************************** ** ** (c) Copyright IBM Corp. 2003 All rights reserved. ** ** This sample program is owned by International Business Machines ** Corporation or one of its subsidiaries ("IBM") and is copyrighted ** and licensed, not sold. ** ** You may copy, modify, and distribute this sample program in any ** form without payment to IBM, for any purpose including developing, ** using, marketing or distributing programs that include or are ** derivative works of the sample program. Licenses to IBM patents ** are expressly excluded from this license. ** The sample program is provided to you on an "AS IS" basis, without ** warranty of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL ** WARRANTIES EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTIC- ** ULAR PURPOSE. Some jurisdictions do not allow for the exclusion or ** limitation of implied warranties, so the above limitations or ** exclusions may not apply to you. IBM shall not be liable for any ** damages you suffer as a result of using, modifying or distributing ** the sample program or its derivatives. ** ** Each copy of any portion of this sample program or any derivative ** work, must include a the above copyright notice and disclaimer of ** waranty. ** ***************************************************************************** ** ** FILENAME : AppletViewer.java ** ** SAMPLE : Information Integrator for Content Version 8 Applet Viewer ** Sample ** ** ABSTRACT : This file is included in the Applet Viewer Sample EAR ** file (AppletViewer.EAR). This is the applet class and ** is used to display documents. Users can work with annotations ** and perform functions such as zoom in/out, rotate, print, etc. ** ** Date : Sept 25, 2003 ** ** Authors : Bryan Daniel (bryand@us.ibm.com) ** Jerald Schoudt ** ** NOTE : AFTER MAKING CHANGES TO THIS CLASS FILE, YOU MUST PACKAGE IT ** INTO A SIGNED JAR FILE. The AppletViewer.jsp web page instructs ** the client Java Plugin to obtain the required class files from ** the cmbview81.jar and AppletViewer.jar files. These files are ** downloaded from the server to the client, and should be located ** in the 'Web Content' folder. (The cmbview81.jar file that is ** in the Web Content folder is Version 8.2 Fixpack 1, which was ** the latest level at the time of this writing. It contains the ** II4C document viewer toolkit and is original installed by II4C ** into the \cmbroot\lib directory. If you have a later fixpack ** level, you may want to copy this jar from c:\cmbroot\lib ** to the 'Web Content' folder.) ** ** Further more, the jar file must be signed since the generic ** doc viewer object contained in the applet will try to make ** a direct connection to the resource manager server to retrieve ** the document (instead of having the document first go through ** the mid tier server). Making a connection to a machine other ** than the web server will cause a security exception, which is ** why you must sign the jar file. ** ** To create a new jar file: ** ------------------------- ** 1) Go to a command window. ** ** 2) Change to the <wsad workspace>\AppletViewer\Web Content dir ** and remove the AppletViewer.jar file. ** ** For example: ** - cd "C:\Documents and Settings\admin\My Documents\ ** wsad\workspace\AppletViewer\Web Content" ** - del AppletViewer.jar ** ** 3) Change to the <wsad workspace>\AppletViewer\Web Content\ ** WEB-INF\classes dir. ** ** For example: ** - cd "C:\Documents and Settings\admin\My Documents\wsad\ ** workspace\AppletViewer\Web Content\WEB-INF\classes" ** ** 4) Use the "jar -cvf" command to create a new AppletViewer.jar ** file containing the following files: ** ** AppletViewer$AnnotationServicesCallbacks.class, ** AppletViewer$LoadedDoc.class ** AppletViewer$StreamingDocServicesCallbacks.class ** AppletViewer.class ** ** The AppletViewer.jar file should be created in the ** 'Web Content' dir. ** ** For example: ** - jar -cvf "C:\Documents and Settings\admin\My Documents\ ** wsad\workspace\AppletViewer\Web Content\AppletViewer.jar" ** AppletViewer$AnnotationServicesCallbacks.class ** AppletViewer$LoadedDoc.class ** AppletViewer$StreamingDocServicesCallbacks.class AppletViewer.class ** ** ** To sign the new jar file: ** ------------------------- ** 1) Go to a command window. ** 2) Change to the <wsad workspace>\AppletViewer\Web Content dir. ** ** For example: ** - cd "C:\Documents and Settings\admin\My Documents\ ** wsad\workspace\AppletViewer\Web Content" ** ** 3) Generate a test certificate by entering: ** keytool -genkey -keystore viewer.store -alias viewercert -validity 365 ** ** 4) Export the certificate by entering: ** keytool -export -keystore viewer.store -alias viewercert -file viewer.cer ** ** 5) Sign the jar file by typing: ** jarsigner -keystore viewer.store AppletViewer.jar viewercert ** ** ** AFTER CREATING A NEW SIGNED JAR FILE, YOU SHOULD REFRESH THE ** FILES IN THE WORKSPACE. To do this, right-click on the ** 'Web Content' folder and choose 'Refresh'. ** ** *****************************************************************************/ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.net.URL; import java.net.URLConnection; import java.util.Iterator; import java.util.Properties; import java.util.Vector; import javax.swing.Action; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JToolBar; import com.ibm.mm.beans.CMBPrivilege; import com.ibm.mm.viewer.CMBDocument; import com.ibm.mm.viewer.CMBGenericDocClosedEvent; import com.ibm.mm.viewer.CMBGenericDocClosedListener; import com.ibm.mm.viewer.CMBGenericDocOpenedEvent; import com.ibm.mm.viewer.CMBGenericDocOpenedListener; import com.ibm.mm.viewer.CMBGenericDocViewer2; import com.ibm.mm.viewer.CMBStreamingDocServices; import com.ibm.mm.viewer.CMBStreamingDocServicesCallbacks; import com.ibm.mm.viewer.annotation.CMBAnnotationServices; import com.ibm.mm.viewer.annotation.CMBAnnotationServicesCallbacks; import com.ibm.mm.viewer.annotation.CMBAnnotationSet; import com.ibm.mm.viewer.annotation.CMBPageAnnotation; import com.ibm.mm.viewer.annotation.CMBTextAnnotation; import com.lowagie.text.Document; import com.lowagie.text.Image; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.RandomAccessFileOrArray; import com.lowagie.text.pdf.codec.TiffImage; public class AppletViewer extends JApplet implements CMBGenericDocOpenedListener, CMBGenericDocClosedListener, ActionListener { private Properties currEngineProperties = null; private Properties currConfigProperties = null; private CMBStreamingDocServices currStreamingDocServices; private CMBAnnotationServices currAnnoServices; private CMBGenericDocViewer2 myGenDocViewer; private int paramNumDocs; private String[] docPaths; private InputStream annis = null; private boolean openingDoc = true; private Vector loadedDocsList; public String descargados; public String transferencias; public String type; public boolean doOperation = false; /************************************************************** * Initializes the applet */ public void init() { try { //+POR SOLICITUD BBVA+//+POR SOLICITUD BBVA+System.out..println("Linea 1"); // This line prevents the "Swing: checked access to system event queue" message seen in some browsers. getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); getContentPane().setLayout(new BorderLayout()); // Create engine properties currEngineProperties = new Properties(); currEngineProperties.put("ENGINES", "2"); currEngineProperties.put("ENGINE1_CLASSNAME", "com.ibm.mm.viewer.mstech.CMBMSTechDocumentEngine"); currEngineProperties.put("ENGINE2_CLASSNAME", "com.ibm.mm.viewer.CMBJavaDocumentEngine"); currEngineProperties.put("DOCTYPE_AUTODETECT", "true"); // Get the viewer configuration properties currConfigProperties = new Properties(); System.out.println("Linea 2"); URL configURL = new URL(getCodeBase(), "CMBViewerConfiguration.properties"); System.out.println("Linea 3"); URLConnection configURLConn = configURL.openConnection(); System.out.println("Linea 4"); InputStream configInputStream = configURLConn.getInputStream(); currConfigProperties.load(configInputStream); configInputStream.close(); // Create document and annotation services objects currStreamingDocServices = new CMBStreamingDocServices(new StreamingDocServicesCallbacks(), currEngineProperties); currAnnoServices = new CMBAnnotationServices(new AnnotationServicesCallbacks()); // Create generic document viewer object myGenDocViewer = new CMBGenericDocViewer2(currStreamingDocServices, currAnnoServices, currConfigProperties); getContentPane().add(myGenDocViewer, BorderLayout.CENTER); myGenDocViewer.setBackground(Color.white); setSize(0, 0); // Add listener to generic document viewer object myGenDocViewer.addDocOpenedListener(this); myGenDocViewer.addDocClosedListener(this); // Add this class as a listener for events thrown by the new // "saveAs_doc" button added to the "OperationToolbar" toolbar JToolBar tb = myGenDocViewer.getToolBar("OperationToolbar"); Component components[] = tb.getComponents(); // Have to go through toolbar components to // find button that we are interested in. for (int i = 0; i < components.length; i++) { if (components[i] instanceof JButton) { JButton button = (JButton) components[i]; Action act = button.getAction(); String name = (String) act.getValue("Name"); System.out.println("name:::::" + name); // If this is the "saveAs_doc" button, add // this class as a listener object if (name.equalsIgnoreCase("saveAs_doc")) button.addActionListener(this); if (name.equalsIgnoreCase("Save Document") || name.equalsIgnoreCase("Guardar documento")) { System.out.println("listener para Save Document"); button.addActionListener(this); } } } // Init list to keep track of loaded documents loadedDocsList = new Vector(); // Now that the GUI is initialized, load specified document String strDoc = getParameter("document"); loadDocument(strDoc); descargados = getParameter("descargados"); transferencias = getParameter("transferencias"); type = getParameter("type"); } catch (Exception e) { e.printStackTrace(); } } // end init() /************************************************************** * Loads a document and its annotations into document viewer * @param docid document id */ public void loadDocument(String docid) { try { System.out.println("loadDocument() called. docid = " + docid); // Lets see if this document has already been opened. // If so, then lets go to that page // for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc doc = (LoadedDoc) loadedDocsList.elementAt(i); if (docid.equals(doc.docid)) { System.out.println("Doc already loaded!!"); myGenDocViewer.activateDocument(doc.document); return; } } // Get mimetype of the first part. The generic doc // viewer object will make calls to the document // services callback class to asynchronously load // another other parts. String partMimeType = getPartMimeType(docid, "0"); System.out.println("partMimeType = " + partMimeType); // Get number of parts int numParts = getNumParts(docid); System.out.println("numParts = " + numParts); // Get url location of the first part of this document String docURL = getDocURL(docid, "0"); System.out.println("docURL = " + docURL); // Get inputstream from document url URL url1 = new URL(docURL); URLConnection urlConnection1 = url1.openConnection(); InputStream docInputStream = urlConnection1.getInputStream(); // Load document CMBDocument currDocument = myGenDocViewer.loadDocument(docInputStream, numParts, partMimeType, partMimeType, null, null); if (currDocument == null) { System.out.println("AppletViewer.loadDocument - currDocument is null"); } // Get url location of annotation part String annURL = getAnnotationURL(docid); System.out.println("annURL = " + annURL); // If there is no annotation part, then create inputstream // to an empty byte array. Else create inputstream to the // url location. InputStream annInputStream; if (annURL == null) { annInputStream = new ByteArrayInputStream(new byte[0]); } else { URL url2 = new URL(annURL); URLConnection urlConnection2 = url2.openConnection(); annInputStream = urlConnection2.getInputStream(); } // Get position of annotations int annPosition = currDocument.getAnnotationPosition(); if (annPosition == 0) annPosition = 14336; // Load annotations CMBAnnotationSet annSet = myGenDocViewer.loadAnnotations(annInputStream, "application/vnd.ibm.modcap", annPosition, 1, 0); // Get privilege information String privInfo = getPrivInfo(docid); System.out.println("Privilege Info : " + privInfo); // Keep track of what documents are currently loaded LoadedDoc docInfo = new LoadedDoc(currDocument, annSet, docid, privInfo); loadedDocsList.addElement(docInfo); // Set permissions for individual annotations. // // The authority is still maintained in the server. For example, if // we set canUpdate() to true, but the access control on the server // does not allow this privilege, then an error will occur when the // user tries to save the annotation. Use this method to keep user // from doing something the server will not allow. // // NOTE: Defect in current code base causes these methods not to work. // As a result, users can change annotations while viewing, but will // later get an error when they try to save their changes (if they // dont have the right permissions). The fix for this defect is // planned to be inclded in the next fixpack. java.util.Iterator iter = annSet.getIterator(); CMBPageAnnotation page; while (iter.hasNext()) { page = (CMBPageAnnotation) iter.next(); page.setCanUpdate(docInfo.checkPriv("CMB_PRIV_MODIFY_SINGLE_ANNOTATION")); page.setCanShow(docInfo.checkPriv("CMB_PRIV_VIEW_ANNOTATION")); } // Show document in viewer myGenDocViewer.showDocument(currDocument, annSet, "Picture" + loadedDocsList.size()); myGenDocViewer.setSize(500, 500); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } catch (Exception e) { e.printStackTrace(); } } // end loadDocument() /************************************************************** * Returns mime type of specified part * @param docid Document id * @param strPartNum Part number */ private String getPartMimeType(String docid, String strPartNum) { String mimeType = ""; try { // Create properties object to hold getPartMimeType command Properties properties = new Properties(); properties.put("command", "getPartMimeType"); properties.put("docid", docid); properties.put("partNum", strPartNum); // Send command to servlet URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); sendCommand(urlConnection, properties); // Get response ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); mimeType = (String) objInputStream.readObject(); objInputStream.close(); } catch (Exception e) { e.printStackTrace(); } return mimeType; } // end getPartMimeType /************************************************************** * Returns the URL location of specified document part * @param docid Document id * @param strPartNum Part number */ private String getDocURL(String docid, String strPartNum) { String docURL = ""; try { // Create properties object to hold getDocURL command Properties properties = new Properties(); properties.put("command", "getDocURL"); properties.put("docid", docid); properties.put("partNum", strPartNum); // Send command to servlet URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); sendCommand(urlConnection, properties); // Get response ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); docURL = (String) objInputStream.readObject(); objInputStream.close(); } catch (Exception e) { e.printStackTrace(); } return docURL; } // end getDocURL() /************************************************************** * Returns number of parts in specified document * @param docid Document id */ private int getNumParts(String docid) { int numParts = 0; try { // Create properties object to hold getNumParts command Properties properties = new Properties(); properties.put("command", "getNumParts"); properties.put("docid", docid); // Send command to servlet URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); sendCommand(urlConnection, properties); // Get response ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); String strNumParts = (String) objInputStream.readObject(); objInputStream.close(); numParts = new Integer(strNumParts).intValue(); } catch (Exception e) { e.printStackTrace(); } return numParts; } // end getNumParts /************************************************************** * Returns URL location of annotation part for specified doc * @param docid Document id */ private String getAnnotationURL(String docid) { String annURL = ""; try { // Create properties object to hold getAnnURL command Properties properties = new Properties(); properties.put("command", "getAnnURL"); properties.put("docid", docid); // Send command to servlet URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); sendCommand(urlConnection, properties); // Get response ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); annURL = (String) objInputStream.readObject(); objInputStream.close(); } catch (Exception e) { e.printStackTrace(); } return annURL; } // end getAnnotationURL /************************************************************** * Returns a string of privilege information * @param docid Document id */ private String getPrivInfo(String docid) { String strPrivInfo = ""; try { // Create properties object to hold getPrivInfo command Properties properties = new Properties(); properties.put("command", "getPrivInfo"); properties.put("docid", docid); // Send command to servlet URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); sendCommand(urlConnection, properties); // Get response ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); strPrivInfo = (String) objInputStream.readObject(); objInputStream.close(); } catch (Exception e) { e.printStackTrace(); } return strPrivInfo; } // end getPrivInfo() /************************************************************** * Sends command to the applet servlet controller * @param urlConnection URL connection to servlet controller * @param command Properties object which contains the task * the applet wants the servlet to perform */ private void sendCommand(URLConnection urlConnection, Properties command) { try { // inform the connection that we will send output and accept input urlConnection.setDoInput(true); urlConnection.setDoOutput(true); // Don't use a cached version of URL connection. urlConnection.setUseCaches(false); urlConnection.setDefaultUseCaches(false); // Specify the content type that we will send binary data urlConnection.setRequestProperty("Content-Type", "application/octet-stream"); // Send command ObjectOutputStream objOutputStream = new ObjectOutputStream(urlConnection.getOutputStream()); objOutputStream.writeObject(command); objOutputStream.flush(); objOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } // end sendCommand() /************************************************************** * Start function */ public void start() { return; } // end start() /************************************************************** * Handles event when a user closes one of the documents * being viewed in the document viewer * @param event Event object */ public void genericDocClosed(CMBGenericDocClosedEvent event) { CMBDocument document = event.getDocument(); LoadedDoc loadedDoc = null; // Find document in the list of loaded docs // and remove once it is found for (int i = 0; i < loadedDocsList.size(); i++) { loadedDoc = (LoadedDoc) loadedDocsList.elementAt(i); if (loadedDoc.document.equals(document)) { loadedDocsList.removeElementAt(i); break; } } } // end genericDocClosed() /************************************************************** * Handles event when a document is opened in the viewer * by firing the 'fit in window' event. * @param event Event object */ public void genericDocOpened(CMBGenericDocOpenedEvent event) { // Get toolbar components JToolBar tb = myGenDocViewer.getToolBar("OperationToolbar"); Component components[] = tb.getComponents(); // Have to go through toolbar components to // find button that we are interested in. for (int i = 0; i < components.length; i++) { if (components[i] instanceof JButton) { JButton button = (JButton) components[i]; Action act = button.getAction(); String name = (String) act.getValue("Name"); // If this is the "fit_window" button, then // programatically click it if (name.equalsIgnoreCase("fit_window")) { button.doClick(); break; } } } } // end genericDocOpened() /************************************************************** * Handles the actionPerformed event. This method was added to * handle when the user clicks on the custom toolbar button that * was added to the operation toolbar. * @param e Event object */ public void actionPerformed(ActionEvent e) { System.out.println("e.getActionCommand():::::" + e.getActionCommand()); // Check if the saveAs_doc button was pressed if (e.getActionCommand().equalsIgnoreCase("saveAs_doc")) { System.out.println("User pressed saveAs_doc toolbar button!"); // output to applet console CMBDocument doc = myGenDocViewer.getSelectedDocument(); // Add implementation for this event. For example, // write doc to disk, assuming applet security // has been addressed via certificates/policyfiles... } if (e.getActionCommand().equalsIgnoreCase("save_doc")) { System.out.println("dentro del listener del evento save_doc"); /*myGenDocViewer.setHabilitarGrabar(true); myGenDocViewer.getSelectedDocument().setModified(true); myGenDocViewer.getSelectedAnnotationSet().setDirty(true);*/ int respuesta = JOptionPane.showConfirmDialog(null, "Est seguro que desea guardar los cambios aplicados al documento?", "Confirmar", JOptionPane.YES_NO_OPTION); switch (respuesta) { case JOptionPane.NO_OPTION: myGenDocViewer.setHabilitarGrabar(Boolean.TRUE); doOperation = false; break; case JOptionPane.YES_OPTION: myGenDocViewer.setHabilitarGrabar(Boolean.FALSE); doOperation = true; break; } } } // end actionPerformed() /*************************************************************************** * * Private inner class which handles callbacks from CMBStreamingDocServies * and provides document services functionality to the document viewer. * ***************************************************************************/ private class StreamingDocServicesCallbacks extends CMBStreamingDocServicesCallbacks implements Serializable { /************************************************************** * Constructor */ StreamingDocServicesCallbacks() { } /************************************************************** * Retrieve a background form. */ public InputStream getForm(CMBDocument document, String formName) { System.out.println("***** StreamingDocServicesCallbacks.getForm called!!!"); return null; } /************************************************************** * Returns true if the user is allowed to print the document */ public boolean getPrintPrivilege(CMBDocument document) { System.out.println("***** StreamingDocServicesCallbacks.getPrintPrivilege called!!!"); try { // Find document information and then determine if // specified privilege is in privString. for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc docInfo = (LoadedDoc) loadedDocsList.elementAt(i); if (document.equals(docInfo.document)) { // Found doc object - now check priv return docInfo.checkPriv("CMB_PRIV_PRINT"); } } } catch (Exception e) { e.printStackTrace(); } return false; } /************************************************************** * Returns an inputstream to the specified document part. * This is called by the generic document viewer when it needs * to obtain other parts of the document. */ public InputStream getPart(CMBDocument document, int partNumber, StringBuffer outMimeType) { System.out.println("***** StreamingDocServicesCallbacks.getPart called!!!"); InputStream docInputStream = null; try { // First get the docid for this document. Since we can't directly // obtain the docid from the CMBDocument object, we must search // for it in our list of open documents. String docid = ""; for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc doc = (LoadedDoc) loadedDocsList.elementAt(i); if (document.equals(doc.document)) { docid = doc.docid; break; } } // Now that we have the docid, let's get the mimetype for this part. // This is done by sending a command to the applet controller // servlet to get this information. URL url1 = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection1 = url1.openConnection(); Properties properties = new Properties(); properties.put("command", "getPartMimeType"); properties.put("docid", docid); properties.put("partNum", new Integer(partNumber).toString()); sendCommand(urlConnection1, properties); ObjectInputStream objInputStream1 = new ObjectInputStream(urlConnection1.getInputStream()); String mimeType = (String) objInputStream1.readObject(); objInputStream1.close(); // Set the outMimeType parameter if (outMimeType != null) { outMimeType.setLength(0); outMimeType.append(mimeType); } // Now lets get the url for this part. // This done by the applet controller servlet. URL url2 = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection2 = url2.openConnection(); properties.clear(); properties.put("command", "getDocURL"); properties.put("docid", docid); properties.put("partNum", new Integer(partNumber).toString()); sendCommand(urlConnection2, properties); ObjectInputStream objInputStream2 = new ObjectInputStream(urlConnection2.getInputStream()); String strDocURL = (String) objInputStream2.readObject(); objInputStream2.close(); // Lastly, now that we have the part URL, create an inputstream to it. URL docURL = new URL(strDocURL); URLConnection docURLConnection = docURL.openConnection(); docInputStream = docURLConnection.getInputStream(); } catch (Exception e) { e.printStackTrace(); } return docInputStream; } /************************************************************** * Retrieve a document annotation. */ public InputStream getAnnotation(CMBDocument document, int annotationNumber) { System.out.println("***** StreamingDocServicesCallbacks.getAnnotation called!!!"); return null; } /************************************************************** * Retrieve a document's resources. */ public InputStream getResources(CMBDocument document) { // No support for OnDemand objects in the applet yet so this should never get called System.out.println("***** StreamingDocServicesCallbacks.getResources called!!!"); InputStream resourceStream = new ByteArrayInputStream(new byte[0]); return resourceStream; } /************************************************************** * Returns true if trace is enabled */ public boolean traceEnabled() { return false; } /************************************************************** * Writes specified trace message to standard output */ public void trace(String message) { System.out.println("StreamingDocServicesCallbacks.trace -- " + message); return; } /************************************************************** * Sends command to applet controller servlet */ private void sendCommand(URLConnection urlConnection, Properties command) { try { // inform the connection that we will send output and accept input urlConnection.setDoInput(true); urlConnection.setDoOutput(true); // Don't use a cached version of URL connection. urlConnection.setUseCaches(false); urlConnection.setDefaultUseCaches(false); // Specify the content type that we will send binary data urlConnection.setRequestProperty("Content-Type", "application/octet-stream"); // Send command ObjectOutputStream objOutputStream = new ObjectOutputStream(urlConnection.getOutputStream()); objOutputStream.writeObject(command); objOutputStream.flush(); objOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } } // end StreamingDocServicesCallbacks class /*************************************************************************** * * Private inner class which handles callbacks from CMBAnnotationDocServices * and provides annotation services functionality to the document viewer. * ***************************************************************************/ private class AnnotationServicesCallbacks extends CMBAnnotationServicesCallbacks implements Serializable { /************************************************************** * Retrieve an annotation part. */ public InputStream getAnnotationPart(CMBAnnotationSet as, int i) { // CM annotations are stored as a single part, so this method is not // needed for viewing CM documents (since the annotation part is already // loaded in the loadDocument() method. System.out.println("----------AnnotationServicesCallbacks.getAnnotationPart()"); return null; } /************************************************************** * Returns true if specified privilege is allowed. */ public boolean getPrivilege(CMBAnnotationSet as, int priv) { System.out.println("----------AnnotationServicesCallbacks.getPrivilege()"); try { // Find document information and then determine if // specified privilege is in privString. for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc docInfo = (LoadedDoc) loadedDocsList.elementAt(i); if (as.equals(docInfo.annSet)) { // Found doc object - now check priv if (priv == CMBPrivilege.CMB_PRIV_CREATE_ANNOTATION) return docInfo.checkPriv("CMB_PRIV_CREATE_ANNOTATION"); if (priv == CMBPrivilege.CMB_PRIV_DELETE_ANNOTATION) return docInfo.checkPriv("CMB_PRIV_DELETE_ANNOTATION"); if (priv == CMBPrivilege.CMB_PRIV_VIEW_ANNOTATION) return docInfo.checkPriv("CMB_PRIV_VIEW_ANNOTATION"); if (priv == CMBPrivilege.CMB_PRIV_PRINT) return docInfo.checkPriv("CMB_PRIV_PRINT"); break; } } } catch (Exception e) { e.printStackTrace(); } return false; } /************************************************************** * Add an annotation part */ public int addAnnotationPart(CMBAnnotationSet as, byte[] data) { System.out.println("----------AnnotationServicesCallbacks.addAnnotationPart()"); if (doOperation) { try { // First get the docid for this document. Since we can't directly // obtain the docid from the CMBAnnotationSet object, we must search // for it in our list of open documents. // String docid = ""; for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc doc = (LoadedDoc) loadedDocsList.elementAt(i); if (as.equals(doc.annSet)) { docid = doc.docid; break; } } // Send add annotation command to servlet, along // with annotation byte array URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); Properties properties = new Properties(); properties.put("command", "addAnnPart"); properties.put("docid", docid); properties.put("annotation", data); sendCommand(urlConnection, properties); // Get return code from servlet ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); String rc = (String) objInputStream.readObject(); objInputStream.close(); System.out.println("addAnnotationPart rc = " + rc); //updateDocumentAnnotation(docid); //para agregar las anotaciones al pdf original convertDocument(docid); } catch (Exception e) { e.printStackTrace(); } } /*else { habilitarBotonGrabar(); }*/ return -1; } /************************************************************** * Updates an existing annotation. part */ public void updateAnnotationPart(CMBAnnotationSet as, byte[] data, int index) { System.out.println("----------AnnotationServicesCallbacks.updateAnnotationPart()"); if (doOperation) { try { // First get the docid for this document. Since we can't directly // obtain the docid from the CMBAnnotationSet object, we must search // for it in our list of open documents. // String docid = ""; for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc doc = (LoadedDoc) loadedDocsList.elementAt(i); if (as.equals(doc.annSet)) { docid = doc.docid; break; } } // Send update annotation command to servlet, along // with annotation byte array URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); Properties properties = new Properties(); properties.put("command", "updateAnnPart"); properties.put("docid", docid); properties.put("annotation", data); properties.put("index", new Integer(index).toString()); sendCommand(urlConnection, properties); // Get return code from servlet ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); String rc = (String) objInputStream.readObject(); objInputStream.close(); System.out.println("updateAnnotationPart rc = " + rc); //updateDocumentAnnotation(docid); //para agregar las anotaciones al pdf original convertDocument(docid); } catch (Exception e) { e.printStackTrace(); } } /*else { habilitarBotonGrabar(); }*/ } /************************************************************** * Removes an annotation part */ public void removeAnnotationPart(CMBAnnotationSet as, int index) { System.out.println("----------AnnotationServicesCallbacks.removeAnnotationPart()"); if (doOperation) { try { // First get the docid for this document. Since we can't directly // obtain the docid from the CMBAnnotationSet object, we must search // for it in our list of open documents. // String docid = ""; for (int i = 0; i < loadedDocsList.size(); i++) { LoadedDoc doc = (LoadedDoc) loadedDocsList.elementAt(i); if (as.equals(doc.annSet)) { docid = doc.docid; break; } } // Send remove annotation command to servlet URL url = new URL(getCodeBase(), "AppletController"); URLConnection urlConnection = url.openConnection(); Properties properties = new Properties(); properties.put("command", "removeAnnPart"); properties.put("docid", docid); properties.put("index", new Integer(index).toString()); sendCommand(urlConnection, properties); // Get return code from servlet ObjectInputStream objInputStream = new ObjectInputStream(urlConnection.getInputStream()); String rc = (String) objInputStream.readObject(); objInputStream.close(); System.out.println("removeAnnotationPart rc = " + rc); //updateDocumentAnnotation(docid); //para agregar las anotaciones al pdf original convertDocument(docid); } catch (Exception e) { e.printStackTrace(); } } /*else { habilitarBotonGrabar(); }*/ } /************************************************************** * Returns true if trace is enabled */ public boolean traceEnabled() { return false; } /************************************************************** * Writes specified trace message to standard output */ public void trace(String message) { System.out.println("AnnotationServicesCallbacks.trace -- " + message); } /************************************************************** * Sends command to applet controller servlet */ private void sendCommand(URLConnection urlConnection, Properties command) { try { // inform the connection that we will send output and accept input urlConnection.setDoInput(true); urlConnection.setDoOutput(true); // Don't use a cached version of URL connection. urlConnection.setUseCaches(false); urlConnection.setDefaultUseCaches(false); // Specify the content type that we will send binary data urlConnection.setRequestProperty("Content-Type", "application/octet-stream"); // Send command ObjectOutputStream objOutputStream = new ObjectOutputStream(urlConnection.getOutputStream()); objOutputStream.writeObject(command); objOutputStream.flush(); objOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } } // end AnnotationServicesCallbacks class /*************************************************************************** * * Private inner class which holds information about which * documents are currently loaded in the document viewer. * ***************************************************************************/ private class LoadedDoc { public CMBDocument document; public CMBAnnotationSet annSet; public String docid; public String privInfo; public LoadedDoc(CMBDocument document, CMBAnnotationSet annSet, String docid, String privInfo) { this.document = document; this.annSet = annSet; this.docid = docid; this.privInfo = privInfo; } public boolean checkPriv(String privName) { boolean rc = false; try { // convert strings to lower case so we can easily find chars privName = privName.toLowerCase(); String tmpPrivInfoStr = privInfo.toLowerCase(); // Find the "<priv>=<val>" string in the privInfo string int x = tmpPrivInfoStr.indexOf(privName); int y = tmpPrivInfoStr.indexOf(",", x); if (y < 0) y = tmpPrivInfoStr.length(); String priv = tmpPrivInfoStr.substring(x, y); // Get the val portion from the <priv>=<val> string x = priv.indexOf("="); String val = priv.substring(x + 1); // If value is 2, set rc to true if (val.equalsIgnoreCase("2")) rc = true; } catch (Exception e) { System.out.println("Error in LoadedDoc.checkPriv"); e.printStackTrace(); } System.out.println("LoadedDoc.checkPriv: " + privName + " = " + rc); return rc; } } // end LoadedDoc class /** * Habilita el boton Save Document */ public void habilitarBotonGrabar() { JToolBar tb = myGenDocViewer.getToolBar("OperationToolbar"); Component components[] = tb.getComponents(); // Have to go through toolbar components to // find button that we are interested in. for (int i = 0; i < components.length; i++) { if (components[i] instanceof JButton) { JButton button = (JButton) components[i]; Action act = button.getAction(); String name = (String) act.getValue("Name"); if (name.equalsIgnoreCase("Save Document") || name.equalsIgnoreCase("Guardar documento")) { myGenDocViewer.getSelectedDocument().setModified(true); button.setEnabled(myGenDocViewer.canSave()); break; } } } } /** * Devuelve true si el boton Save Document se encuentra habilitado. * Devuelve false si el boton Save Document se encuentra deshabilitado. */ public boolean botonGrabarHabilitado() { boolean habilitado = false; JToolBar tb = myGenDocViewer.getToolBar("OperationToolbar"); Component components[] = tb.getComponents(); // Have to go through toolbar components to // find button that we are interested in. for (int i = 0; i < components.length; i++) { if (components[i] instanceof JButton) { JButton button = (JButton) components[i]; Action act = button.getAction(); String name = (String) act.getValue("Name"); if (name.equalsIgnoreCase("Save Document") || name.equalsIgnoreCase("Guardar documento")) { habilitado = button.isEnabled(); break; } } } return habilitado; } /** * Metodo que crea un PDF a partir del archivo TIF con sus anotaciones * @param docid */ public void convertDocument(String docid) { try { File dir = new File(descargados); if (!dir.exists()) { dir.mkdirs(); } dir = new File(transferencias); if (!dir.exists()) { dir.mkdirs(); } // CARGAR TIF CON ANOTACIONES String tmpFileName = "TMP" + String.valueOf(System.currentTimeMillis()) + ".tif"; OutputStream output = new FileOutputStream(descargados + File.separator + tmpFileName); myGenDocViewer.exportDocument(output, true, false, "image/tiff"); output.close(); // CONVERTIR TIF A PDF RandomAccessFileOrArray myTiffFile = new RandomAccessFileOrArray( descargados + File.separator + tmpFileName); int numberOfPages = TiffImage.getNumberOfPages(myTiffFile); Document TifftoPDF = new Document(); TifftoPDF.setMargins(0, 0, 0, 0); PdfWriter.getInstance(TifftoPDF, new FileOutputStream(transferencias + File.separator + type + "-AN.pdf")); TifftoPDF.open(); for (int i = 1; i <= numberOfPages; i++) { Image tempImage = TiffImage.getTiffImage(myTiffFile, i); float dpiX = tempImage.getDpiX() == 0 ? 200 : tempImage.getDpiX(); float dpiY = tempImage.getDpiY() == 0 ? 200 : tempImage.getDpiY(); float factorX = 72 / dpiX; float factorY = 72 / dpiY; tempImage.scaleAbsolute(factorX * tempImage.getWidth(), factorY * tempImage.getHeight()); TifftoPDF.add(tempImage); } myTiffFile.close(); TifftoPDF.close(); // BORRAR EL TIFF File file = new File(descargados + File.separator + tmpFileName); if (file.delete()) { System.out.println(file.getName() + " eliminado"); } else { file.deleteOnExit(); ; System.out.println("Eliminacion fallo"); } System.out.println("Fin de la creacion del PDF con anotaciones"); } catch (Exception e) { e.printStackTrace(); } } /** * Metodo que obtiene el documento actualizado con sus respectivas anotaciones. * Invoca al metodo que agregara las anotaciones al nuevo PDF * @param docid */ public void updateDocumentAnnotation(String docid) { try { String partMimeType = getPartMimeType(docid, "0"); System.out.println("partMimeType = " + partMimeType); // Get number of parts int numParts = getNumParts(docid); System.out.println("numParts = " + numParts); // Get url location of the first part of this document String docURL = getDocURL(docid, "0"); System.out.println("docURL = " + docURL); // Get inputstream from document url URL url1 = new URL(docURL); URLConnection urlConnection1 = url1.openConnection(); InputStream docInputStream = urlConnection1.getInputStream(); // Load document CMBDocument currDocument = myGenDocViewer.loadDocument(docInputStream, numParts, partMimeType, partMimeType, null, null); if (currDocument == null) { System.out.println("AppletViewer.loadDocument - currDocument is null"); } // Get url location of annotation part String annURL = getAnnotationURL(docid); System.out.println("annURL = " + annURL); // If there is no annotation part, then create inputstream // to an empty byte array. Else create inputstream to the // url location. InputStream annInputStream; if (annURL == null) { annInputStream = new ByteArrayInputStream(new byte[0]); } else { URL url2 = new URL(annURL); URLConnection urlConnection2 = url2.openConnection(); annInputStream = urlConnection2.getInputStream(); } // Get position of annotations int annPosition = currDocument.getAnnotationPosition(); if (annPosition == 0) annPosition = 14336; // Load annotations CMBAnnotationSet annSet = myGenDocViewer.loadAnnotations(annInputStream, "application/vnd.ibm.modcap", annPosition, 1, 0); PdfReader reader = new PdfReader("C://Prueba.pdf"); // input PDF PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("C://Prueba_modified.pdf")); // output PDF Iterator iterator = annSet.getIterator(); while (iterator.hasNext()) { CMBPageAnnotation pageAnnotation = (CMBPageAnnotation) iterator.next(); //System.out.println("tipo:::::"+pageAnnotation.getType()); //System.out.println("nombre:::::"+pageAnnotation.getName()); //System.out.println("pagina:::::"+pageAnnotation.getPageNumber()); CMBTextAnnotation textAnnotation = (CMBTextAnnotation) pageAnnotation; //System.out.println("texto:::::"+textAnnotation.getTextLine()); //System.out.println("posicionX:::::"+textAnnotation.getDrawRect().getX()); //System.out.println("posicionY:::::"+textAnnotation.getDrawRect().getY()); //System.out.println("tamanho:::::"+textAnnotation.getFont().getSize()); //System.out.println("tamanho2D:::::"+textAnnotation.getFont().getSize2D()); if ("TEXT".equals(pageAnnotation.getName().toUpperCase())) { addTextAnnotation(stamper, pageAnnotation.getPageNumber(), (float) textAnnotation.getDrawRect().getX(), (float) textAnnotation.getDrawRect().getY(), textAnnotation.getTextLine(), 12); } } stamper.close(); } catch (Exception e) { e.printStackTrace(); } } /** * Metodo que agrega annotaciones (en texto) al nuevo PDF * @param stamper * @param pageNumber * @param x * @param y * @param text * @param size */ public void addTextAnnotation(PdfStamper stamper, int pageNumber, float x, float y, String text, float size) { try { BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); // set font PdfContentByte over = stamper.getOverContent(pageNumber); float positionX = ((x * 2480) / 1654); float positionY = ((y * 3508) / 2339); // write text over.beginText(); over.setFontAndSize(bf, size); // set font and size over.setTextMatrix(positionX, positionY); // set x,y position (0,0 is at the bottom left) over.showText(text); // set text over.endText(); } catch (Exception e) { e.printStackTrace(); } } } // end AppletViewer class