A.1. Chapter 4—Developing Bundles

A.1.1. The LPD Print Service

A.1.1.1. com/acme/service/print/PrintService.java
package com.acme.service.print;
import java.io.IOException;
import java.net.URL;
/**
 * The PrintService prints contents from a URL or
 * gets status of a print queue.
 */
public interface PrintService {
   /**
    * Prints the contents from the source to the specified printer.
    * @param printer the name of the destination printer
    * @param source the source of the contents to be printed
    * @exception IOException if printing fails
    */
   public void print(String printer, URL source) throws IOException;
   /**
    * Gets the status of the specified printer.
    * @param printer the name of the printer
    * @return the status of the print queue as an array,
    * one element per print job;
    * null if no entries are present in the queue
    */
   public String[] getStatus(String printer) throws IOException;
}

A.1.1.2. com/acme/impl/print/Printer.java
package com.acme.impl.print;
import java.io.*;
import java.net.*;

class Printer {
   private String printServer;

   Printer(String ps) {
      this.printServer = ps;
   }

   /**
    * Sends a request to the printer daemon.
    * @param command a number representing a command
    * @param queue the name of the print queue
    * @param operand the operand needed by the command
    * @return a connection to the printer daemon.
    * @exception java.io.IOException if communication to the daemon
    * fails.
    */
   PrintConnection request(int command, String queue,
      String operand) throws IOException
   {
      Socket s = new Socket(printServer, 515);
      OutputStream out = s.getOutputStream();
      out.write(command);
      out.write(queue.getBytes());
      out.write(32); // write a white space SP
      if (operand != null) {
            out.write(operand.getBytes());
      }
      out.write(10); // write a line feed char LF
      out.flush();
      return new PrintConnection(queue, s);
   }
}

A.1.1.3. com/acme/impl/print/PrintServiceImpl.java
package com.acme.impl.print;
import java.net.*;
import java.io.*;
import java.util.*;
import com.acme.service.print.PrintService;

class PrintServiceImpl implements PrintService {
   private final static int SEND_QUEUE_STATE = 4;
   private final static int RECEIVE_PRINT_JOB = 2;
   private Printer printer;
   private static int jobNumber = 100;

   PrintServiceImpl() {
      printer = new Printer("kontakt");
   }

   public String[] status(String printQueue) throws IOException {
      Vector v = new Vector();
      PrintConnection conn =
         printer.request(SEND_QUEUE_STATE, printQueue, null);
      BufferedReader r = new BufferedReader(conn.getReader());
      String line;
      while ( (line = r.readLine()) != null) {
         v.addElement(line);
      }
      r.close();
      String[] s = null;
      if (v.size() > 0) {
         String entry0 = (String) v.elementAt(0);
         if (! "no entries".equals(entry0)) {
            s = new String[v.size()];
            v.copyInto(s);
         }
      }
      return s;
   }

   public void print(String printQueue, URL src)
      throws IOException
   {
      PrintConnection conn = printer.request(RECEIVE_PRINT_JOB,
            printQueue, null);
      int ack = conn.getAck();
      if (ack != 0)
         throw new IOException("Sending print job to " +
              printQueue + " failed.");
      conn.sendControl(jobNumber, src);
      conn.sendData(jobNumber, src);
      conn.close();
      // generate the next 3-digit job number
      jobNumber = (jobNumber + 1) % 1000;
   }
}

A.1.1.4. com/acme/impl/print/PrintConnection.java
package com.acme.impl.print;
import java.net.*;
import java.io.*;

class PrintConnection {
   private static int RECEIVE_CONTROL = 2;
   private static int RECEIVE_DATA = 3;
   private Socket sock;
   private String host;
   private String printQueue;

   PrintConnection(String q, Socket s) throws IOException {
      this.sock = s;
      this.host = InetAddress.getLocalHost().getHostName();
      this.printQueue = q;
   }
   // Gets messages from the daemon.
   Reader getReader() throws IOException {
      InputStream in = sock.getInputStream();
      return new BufferedReader(new InputStreamReader(in));
   }

   // Gets byte streams from the daemon.
   InputStream getInputStream() throws IOException {
      return sock.getInputStream();
   }

   // Gets an acknowledge byte from the daemon. 0 means success.
   int getAck() throws IOException {
      return sock.getInputStream().read();
   }

   // Sends control sequences to the daemon.
   // This identifies the data that follow and their size.
   void sendControl(int jobNumber, URL src)
      throws IOException
   {
      String ctrlName = "cfA" + jobNumber + host;
      String df_file = "dfA" + jobNumber + host;
      String[] ctrlSeq = new String[] {
            "H" + host,
            "P" + System.getProperty("user.name"),
            "f" + df_file,
            "N" + src.toExternalForm()
      };
      int count = 0;
      for (int i=0; i<ctrlSeq.length; i++) {
          count += ctrlSeq[i].getBytes().length;
      }
      count += ctrlSeq.length;
      OutputStream out = sock.getOutputStream();
      out.write(RECEIVE_CONTROL);
      out.write(Integer.toString(count).getBytes());
      out.write(32);
      out.write(ctrlName.getBytes());
      out.write(10);
      out.flush();
      if (getAck() != 0)
         throw new IOException("Couldn't start sending control "+
             " file to " + printQueue);
      for (int i=0; i<ctrlSeq.length; i++) {
         out.write(ctrlSeq[i].getBytes());
         out.write(10);
      }
      out.write(0);
      out.flush();
      if (getAck() != 0)
         throw new IOException("Failed sending control " +
            "sequence to " + printQueue);
      }

   // Sends data to the daemon. The data source can be a local file
   // or from a URL pointing to a remote location.
   void sendData(int jobNumber,URL src) throws IOException {
      String dataName = "dfA" + jobNumber + host;
      RandomAccessFile raf = null;
      URLConnection uconn = null;
      int count = -1;
      if ("file".equals(src.getProtocol())) {
            raf = new RandomAccessFile(src.getFile(), "r");
            count = (int) raf.length();
      } else {
            uconn = src.openConnection();
            count = uconn.getContentLength();
      }
      if (count == -1)
         throw new IOException("Couldn't determine the length " +
               "of source contents.");
      OutputStream out = sock.getOutputStream();
      out.write(RECEIVE_DATA);
      out.write(Integer.toString(count).getBytes());
      out.write(32);
      out.write(dataName.getBytes());
      out.write(10);
      out.flush();
      if (getAck() != 0)
         throw new IOException("Couldn't start sending " +
            "data file to " + printQueue);
      byte[] buf = new byte[10240];
      int byteRead;
      if ("file".equals(src.getProtocol())) {
         while ( (byteRead = raf.read(buf)) > 0)
            out.write(buf, 0, byteRead);
         raf.close();
      } else {
         BufferedInputStream in =
            new BufferedInputStream(uconn.getInputStream());
         while ( (byteRead = in.read(buf)) > 0)
         out.write(buf, 0, byteRead);
         in.close();
      }
      out.write(0);
      out.flush();
      int ack = getAck();
      if (ack != 0)
         throw new IOException("Failed to send data file to "+
              printQueue);

   }

   // Closes connection to the daemon.
   void close() throws IOException {
      sock.close();
   }
}

A.1.1.5. com/acme/impl/print/Activator.java
package com.acme.impl.print;
import java.util.Properties;
import org.osgi.framework.*;
import com.acme.service.print.PrintService;

public class Activator implements BundleActivator {
   private ServiceRegistration reg;

   public void start(BundleContext ctxt) {
      PrintService svc = new PrintServiceImpl();
      Properties props = new Properties();
      props.put("description", "A sample print service");
      reg = ctxt.registerService(
         "com.acme.service.print.PrintService", svc, props);
   }

   public void stop(BundleContext ctxt) {
      if (reg != null)
         reg.unregister();
   }
}

A.1.1.6. com/acme/impl/print/Manifest
Bundle-Activator: com/acme/impl/print/Activator
Export-Package: com.acme.service.print

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.226.240