DMAPService.java :  » Media » jems » net » kodeninja » jem » server » DMAP » Java Open Source

Java Open Source » Media » jems 
jems » net » kodeninja » jem » server » DMAP » DMAPService.java
package net.kodeninja.jem.server.DMAP;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;

import org.w3c.dom.Node;

import com.apple.dnssd.DNSSD;
import com.apple.dnssd.DNSSDException;
import com.apple.dnssd.DNSSDRegistration;
import com.apple.dnssd.DNSSDService;
import com.apple.dnssd.RegisterListener;
import com.apple.dnssd.TXTRecord;

import net.kodeninja.http.service.HTTPTCPService;
import net.kodeninja.http.service.handlers.GetHandler;
import net.kodeninja.jem.server.JemServer;
import net.kodeninja.jem.server.DMAP.content.DMAPMediaCollection;
import net.kodeninja.jem.server.DMAP.responses.ContentCodesURI;
import net.kodeninja.jem.server.DMAP.responses.DatabasesURI;
import net.kodeninja.jem.server.DMAP.responses.ItemsURI;
import net.kodeninja.jem.server.DMAP.responses.LoginURI;
import net.kodeninja.jem.server.DMAP.responses.LogoutURI;
import net.kodeninja.jem.server.DMAP.responses.MediaRequestURI;
import net.kodeninja.jem.server.DMAP.responses.PlaylistListURI;
import net.kodeninja.jem.server.DMAP.responses.ServerInfoURI;
import net.kodeninja.jem.server.DMAP.responses.UpdateURI;
import net.kodeninja.jem.server.storage.MediaItem;
import net.kodeninja.jem.server.storage.MediaUpdateHook;
import net.kodeninja.util.KNRunnableModule;
import net.kodeninja.util.KNXMLModule;
import net.kodeninja.util.KNModuleInitException;
import net.kodeninja.util.MalformedMimeTypeException;
import net.kodeninja.util.MimeType;

public class DMAPService extends HTTPTCPService implements KNRunnableModule,
    KNXMLModule, RegisterListener, MediaUpdateHook {
  protected String serviceName = "JemServer";
  public final static int DAAP_PORT = 3689;
  protected int lastSession = 0;
  protected int mediaRevision = 0;
  private DNSSDRegistration daapReg = null;
  private DNSSDRegistration dpapReg = null;
  private DMAPRevisionCache revisions = new DMAPRevisionCache();
  private LinkedList<MimeType> transcodingTypes = new LinkedList<MimeType>();

  public DMAPService() {
    super(JemServer.getScheduler(), DAAP_PORT);
  }

  public void xmlInit(Node xmlNode) throws KNModuleInitException {
    for (Node modNode = xmlNode.getFirstChild(); modNode != null; modNode = modNode
        .getNextSibling()) {
      if (modNode.getNodeType() != Node.ELEMENT_NODE)
        continue;
      if (modNode.getNodeName().equals("servicename"))
        serviceName = modNode.getTextContent().trim();
      else if (modNode.getNodeName().equals("port")) {
        String portString = modNode.getTextContent().trim();
        if (portString.length() > 0)
          try {
            setPort(Integer.parseInt(portString));
          } catch (NumberFormatException e) {
            throw new KNModuleInitException("Invalid port.");
          }
        else
          throw new KNModuleInitException("Invalid port.");
      } else if (modNode.getNodeName().equals("transcode"))
        try {
          MimeType m = new MimeType(modNode.getTextContent());
          transcodingTypes.add(m);
        } catch (MalformedMimeTypeException e) {
          throw new KNModuleInitException(
              "Invalid transcode target mimetype: "
                  + modNode.getTextContent());
        }
    }
    mediaChanged();
  }

  @Override
  public void start() {
    if (isStarted() == false) {
      super.start();
      
      JemServer.getMediaStorage().hookMediaUpdate(this);

      // Setup logger for server
      addLogger(JemServer.getInstance());

      // The main get handler
      GetHandler getter = new GetHandler();
      getter.enableChunked(false);
      getter.enableCompression(true);

      // Add handlers to server
      getTransport().addHandler(getter);

      // The URI handlers for the different requests
      ServerInfoURI siURI = new ServerInfoURI(this);
      ContentCodesURI ccURI = new ContentCodesURI(this);
      LoginURI liURI = new LoginURI(this);
      LogoutURI loURI = new LogoutURI(this);
      UpdateURI upURI = new UpdateURI(this);
      DatabasesURI dlURI = new DatabasesURI(this);
      PlaylistListURI plURI = new PlaylistListURI(this);
      MediaRequestURI mrURI = new MediaRequestURI(this);
      ItemsURI itURI = new ItemsURI(this);

      // Add URI handlers to get handler
      getter.addURIHandler(itURI);
      getter.addURIHandler(siURI);
      getter.addURIHandler(ccURI);
      getter.addURIHandler(liURI);
      getter.addURIHandler(loURI);
      getter.addURIHandler(upURI);
      getter.addURIHandler(dlURI);
      getter.addURIHandler(plURI);
      getter.addURIHandler(mrURI);

      // Add URI class hooks
      JemServer.getMediaStorage().hookMediaUpdate(upURI);
      JemServer.getMediaStorage().hookMediaUpdate(dlURI);

      // Set to 1800 seconds, the itunes default
      getTransport().setTimeout(1800000);

      TXTRecord daapDetails = new TXTRecord();
      TXTRecord dpapDetails = new TXTRecord();

      try {
        daapDetails.set("txtvers", "1");
        daapDetails.set("Machine Name", getServerName());
        daapDetails.set("Password", "false");
        daapReg = DNSSD.register(0, 0, getServerName(), "_daap._tcp",
                      (String) null, (String) null,
                      getBoundPort(), daapDetails, this);

        dpapDetails.set("txtvers", "1");
        dpapDetails.set("Version", "65537");
        dpapDetails.set("iPSh Version", "131072");
        dpapDetails.set("Machine Name", getServerName());
        dpapDetails.set("Password", "false");
        dpapReg = DNSSD.register(0, 0, getServerName(), "_dpap._tcp",
                      (String) null, (String) null,
                      getBoundPort(), dpapDetails, this);
      } catch (DNSSDException e) {
        e.printStackTrace();
        daapReg = null;
        dpapReg = null;
      }

      if ((daapReg == null) || (dpapReg == null)) {
        addLog(getName() + ": Error registering service with DNS-SD.");
        JemServer.command().exception();
        return;
      }

      JemServer.getInstance().addLog(
                      getName() + " [" + getServerName()
                          + "] started. (Port: "
                          + getBoundPort() + ")");
    }
  }

  @Override
  public void stop() {
    if (daapReg != null) {
      daapReg.stop();
      daapReg = null;
    }

    if (dpapReg != null) {
      dpapReg.stop();
      dpapReg = null;
    }

    super.stop();
  }

  public void serviceRegistered(DNSSDRegistration registration, int flags,
      String serviceName, String regType, String domain) {

  }

  public void operationFailed(DNSSDService service, int errorCode) {
    addLog("[" + getName() + "] DNS-SD Error Code: " + errorCode);
    JemServer.command().exception();
  }

  public String getServerName() {
    return serviceName;
  }

  public String getServerString() {
    return getName() + "/" + getVersionMajor() + "." + getVersionMinor()
        + "." + getVersionRevision();
  }

  public int createSession() {
    return lastSession++;
  }

  public void closeSession(int sessionId) {
  }

  public synchronized void mediaChanged() {
    mediaRevision++;
    DMAPMediaCollection tmpCol = new DMAPMediaCollection("all");
    JemServer.getMediaStorage().setupCollection(tmpCol);
    revisions.put(new Integer(mediaRevision), tmpCol);
  }

  public synchronized DMAPMediaCollection getRevision(int revision) {
    return revisions.get(new Integer(revision));
  }

  public synchronized int getMediaRevision() {
    return mediaRevision;
  }

  public boolean transcodeItem(MediaItem mi) {
    for (MimeType m : transcodingTypes)
      if (m.equals(JemServer.getMediaStorage().getMimeType(mi)))
        return true;
    return false;
  }

  public InputStream getItemStream(MediaItem mi) {

    InputStream retVal = null;
    try {
      retVal = mi.getURI().toURL().openStream();
      MimeType mimetype = JemServer.getMediaStorage().getMimeType(mi);

      if (transcodeItem(mi)) {
        MimeType destType = MimeType.WILDCARD;
        if (mimetype.getPrimaryType().equals("video"))
          destType = new MimeType("video", "mov");
        else if (mimetype.getPrimaryType().equals("audio"))
          destType = new MimeType("audio", "mpeg");
        else if (mimetype.getPrimaryType().equals("image"))
          destType = new MimeType("image", "jpeg");

        InputStream transRetVal = JemServer.getInstance().requestTranscode(mimetype, destType, retVal);
        if (transRetVal != null)
          retVal = transRetVal;
      }
    } catch (IOException e) {
      e.printStackTrace();
    }

    return retVal;
  }

  @Override
  public String getName() {
    return "JEM DAAP Plugin";
  }

  @Override
  public int getVersionMajor() {
    return 0;
  }

  @Override
  public int getVersionMinor() {
    return 1;
  }

  @Override
  public int getVersionRevision() {
    return 0;
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.