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; }
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); } }
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; } }
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(); } }
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(); } }
Bundle-Activator: com/acme/impl/print/Activator Export-Package: com.acme.service.print
3.147.73.228