Sun Java Solaris Communities My SDN Account Join SDN

1.0 Programmers Guide

1.0 Overview

 
TOC  Prev  Next  

This sample demonstrates how to implement a new DataSource to support an additional protocol, the FTP protocol. There are two classes:

  • DataSource extends PullDataSource and implements intel.media.protocol.PullProtocolHandler.

  • FTPSourceStream implements PullSourceStream.

FTP Data Source


package COM.intel.media.protocol.ftp; import javax.media.protocol.PullDataSource; import javax.media.protocol.SourceStream; import javax.media.protocol.PullSourceStream; import javax.media.Time; import javax.media.Duration; import java.io.*; import java.net.*; import java.util.Vector; public class DataSource extends PullDataSource { public static final int FTP_PORT = 21; public static final int FTP_SUCCESS = 1; public static final int FTP_TRY_AGAIN = 2; public static final int FTP_ERROR = 3; // used to send commands to server protected Socket controlSocket; // used to receive file protected Socket dataSocket; // wraps controlSocket's output stream protected PrintStream controlOut; // wraps controlSocket's input stream protected InputStream controlIn; // hold (possibly multi-line) server response protected Vector response = new Vector(1); // reply code from previous command protected int previousReplyCode; // are we waiting for command reply? protected boolean replyPending; // user login name protected String user = "anonymous"; // user login password protected String password = "anonymous"; // FTP server name protected String hostString; // file to retrieve protected String fileString; public void connect() throws IOException { initCheck(); // make sure the locator is set if (controlSocket != null) { disconnect(); } // extract FTP server name and target filename from locator parseLocator(); controlSocket = new Socket(hostString, FTP_PORT); controlOut = new PrintStream(new BufferedOutputStream( controlSocket.getOutputStream()), true); controlIn = new BufferedInputStream(controlSocket.getInputStream()); if (readReply() == FTP_ERROR) { throw new IOException("connection failed"); } if (issueCommand("USER " + user) == FTP_ERROR) { controlSocket.close(); throw new IOException("USER command failed"); } if (issueCommand("PASS " + password) == FTP_ERROR) { controlSocket.close(); throw new IOException("PASS command failed"); } } public void disconnect() { if (controlSocket == null) { return; } try { issueCommand("QUIT"); controlSocket.close(); } catch (IOException e) { // do nothing, we just want to shutdown } controlSocket = null; controlIn = null; controlOut = null; } public void start() throws IOException { ServerSocket serverSocket; InetAddress myAddress = InetAddress.getLocalHost(); byte[] address = myAddress.getAddress(); String portCommand = "PORT "; serverSocket = new ServerSocket(0, 1); // append each byte of our address (comma-separated) for (int i = 0; i < address.length; i++) { portCommand = portCommand + (address[i] & 0xFF) + ","; } // append our server socket's port as two comma-separated // hex bytes portCommand = portCommand + ((serverSocket.getLocalPort() >>> 8) & 0xFF) + "," + (serverSocket.getLocalPort() & 0xFF); // issue PORT command if (issueCommand(portCommand) == FTP_ERROR) { serverSocket.close(); throw new IOException("PORT"); } // issue RETRieve command if (issueCommand("RETR " + fileString) == FTP_ERROR) { serverSocket.close(); throw new IOException("RETR"); } dataSocket = serverSocket.accept(); serverSocket.close(); } public void stop() { try { // issue ABORt command issueCommand("ABOR"); dataSocket.close(); } catch(IOException e) {} } public String getContentType() { // We don't get MIME info from FTP server. This // implementation makes an attempt guess the type using // the File name and returns "unknown" in the default case. // A more robust mechanisms should // be supported for real-world applications. String locatorString = getLocator().toExternalForm(); int dotPos = locatorString.lastIndexOf("."); String extension = locatorString.substring(dotPos + 1); String typeString = "unknown"; if (extension.equals("avi")) typeString = "video.x-msvideo"; else if (extension.equals("mpg") || extension.equals("mpeg")) typeString = "video.mpeg"; else if (extension.equals("mov")) typeString = "video.quicktime"; else if (extension.equals("wav")) typeString = "audio.x-wav"; else if (extension.equals("au")) typeString = "audio.basic"; return typeString; } public PullSourceStream[] getStreams() { PullSourceStream[] streams = new PullSourceStream[1]; try { streams[0] = new FTPSourceStream(dataSocket.getInputStream()); } catch(IOException e) { System.out.println("error getting streams"); } return streams; } public Time getDuration() { return Duration.DURATION_UNKNOWN; } public void setUser(String user) { this.user = user; } public String getUser() { return user; } public void setPassword(String password) { this.password = password; } public String getPassword() { return password; } private int readReply() throws IOException { previousReplyCode = readResponse(); System.out.println(previousReplyCode); switch (previousReplyCode / 100) { case 1: replyPending = true; // fall through case 2: case 3: return FTP_SUCCESS; case 5: if (previousReplyCode == 530) { if (user == null) { throw new IOException("Not logged in"); } return FTP_ERROR; } if (previousReplyCode == 550) { throw new FileNotFoundException(); } } return FTP_ERROR; } /** * Pulls the response from the server and returns the code as a * number. Returns -1 on failure. */ private int readResponse() throws IOException { StringBuffer buff = new StringBuffer(32); String responseStr; int c; int continuingCode = -1; int code = 0; response.setSize(0); while (true) { while ((c = controlIn.read()) != -1) { if (c == '\r') { if ((c = controlIn.read()) != '\n') { buff.append('\r'); } } buff.append((char)c); if (c == '\n') { break; } } responseStr = buff.toString(); buff.setLength(0); try { code = Integer.parseInt(responseStr.substring(0, 3)); } catch (NumberFormatException e) { code = -1; } catch (StringIndexOutOfBoundsException e) { /* this line doesn't contain a response code, so * we just completely ignore it */ continue; } response.addElement(responseStr); if (continuingCode != -1) { /* we've seen a XXX- sequence */ if (code != continuingCode || (responseStr.length() >= 4 && responseStr.charAt(3) == '-')) { continue; } else { /* seen the end of code sequence */ continuingCode = -1; break; } } else if (responseStr.length() >= 4 && responseStr.charAt(3) == '-') { continuingCode = code; continue; } else { break; } } previousReplyCode = code; return code; } private int issueCommand(String cmd) throws IOException { int reply; if (replyPending) { if (readReply() == FTP_ERROR) { System.out.print("Error reading pending reply\n"); } } replyPending = false; do { System.out.println(cmd); controlOut.print(cmd + "\r\n"); reply = readReply(); } while (reply == FTP_TRY_AGAIN); return reply; } /** * Parses the mediaLocator field into host and file strings */ protected void parseLocator() { initCheck(); String rest = getLocator().getRemainder(); System.out.println("Begin parsing of: " + rest); int p1, p2 = 0; p1 = rest.indexOf("//"); p2 = rest.indexOf("/", p1+2); hostString = rest.substring(p1 + 2, p2); fileString = rest.substring(p2); System.out.println("host: " + hostString + " file: " + fileString); } }

Source Stream


package intel.media.protocol.ftp; import java.io.*; import javax.media.protocol.ContentDescriptor; import javax.media.protocol.PullSourceStream; import javax.media.protocol.SourceStream; public class FTPSourceStream implements PullSourceStream { protected InputStream dataIn; protected boolean eofMarker; protected ContentDescriptor cd; public FTPSourceStream(InputStream in) { this.dataIn = in; eofMarker = false; cd = new ContentDescriptor("unknown"); } // SourceSteam methods public ContentDescriptor getContentDescriptor() { return cd; } public void close() throws IOException { dataIn.close(); } public boolean endOfStream() { return eofMarker; } // PullSourceStream methods public int available() throws IOException { return dataIn.available(); } public int read(byte[] buffer, int offset, int length) throws IOException { int n = dataIn.read(buffer, offset, length); if (n == -1) { eofMarker = true; } return n; } public boolean willReadBlock() throws IOException { if(eofMarker) { return true; } else { return dataIn.available() == 0; } } public long getContentLength() { return SourceStream.LENGTH_UNKNOWN; } }

TOC  Prev  Next