[Bedework-commit] exchgsynch r7 - in trunk/server/src/org/bedework/exchgsynch: . web

svnadmin at bedework.org svnadmin at bedework.org
Tue Sep 28 14:10:33 EDT 2010


Author: douglm
Date: 2010-09-28 14:10:32 -0400 (Tue, 28 Sep 2010)
New Revision: 7

Added:
   trunk/server/src/org/bedework/exchgsynch/web/
   trunk/server/src/org/bedework/exchgsynch/web/ExsynchServlet.java
   trunk/server/src/org/bedework/exchgsynch/web/MethodBase.java
Removed:
   trunk/server/src/org/bedework/exchgsynch/ExchangeCallback.java
   trunk/server/src/org/bedework/exchgsynch/ExchangeSubscription.java
   trunk/server/src/org/bedework/exchgsynch/ExchangeSynch.java
   trunk/server/src/org/bedework/exchgsynch/ExchangeSynchIntf.java
   trunk/server/src/org/bedework/exchgsynch/ExsynchConfig.java
   trunk/server/src/org/bedework/exchgsynch/SynchException.java
   trunk/server/src/org/bedework/exchgsynch/bwimpl/
Log:


Deleted: trunk/server/src/org/bedework/exchgsynch/ExchangeCallback.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/ExchangeCallback.java	2010-09-28 18:10:22 UTC (rev 6)
+++ trunk/server/src/org/bedework/exchgsynch/ExchangeCallback.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -1,40 +0,0 @@
-/* **********************************************************************
-    Copyright 2010 Rensselaer Polytechnic Institute. All worldwide rights reserved.
-
-    Redistribution and use of this distribution in source and binary forms,
-    with or without modification, are permitted provided that:
-       The above copyright notice and this permission notice appear in all
-        copies and supporting documentation;
-
-        The name, identifiers, and trademarks of Rensselaer Polytechnic
-        Institute are not used in advertising or publicity without the
-        express prior written permission of Rensselaer Polytechnic Institute;
-
-    DISCLAIMER: The software is distributed" AS IS" without any express or
-    implied warranty, including but not limited to, any implied warranties
-    of merchantability or fitness for a particular purpose or any warrant)'
-    of non-infringement of any current or pending patent rights. The authors
-    of the software make no representations about the suitability of this
-    software for any particular purpose. The entire risk as to the quality
-    and performance of the software is with the user. Should the software
-    prove defective, the user assumes the cost of all necessary servicing,
-    repair or correction. In particular, neither Rensselaer Polytechnic
-    Institute, nor the authors of the software are liable for any indirect,
-    special, consequential, or incidental damages related to the software,
-    to the maximum extent the law permits.
-*/
-
-package org.bedework.exchgsynch;
-
-/** Calls from the calendar system to the exchange synch processor.
- *
- * @author Mike Douglass
- */
-public abstract class ExchangeCallback {
-  /** Update or add a subscription.
-   *
-   * @param sub
-   * @throws WebdavException
-   */
-  public abstract void subscribeRequest(ExchangeSubscription sub) throws SynchException;
-}

Deleted: trunk/server/src/org/bedework/exchgsynch/ExchangeSubscription.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/ExchangeSubscription.java	2010-09-28 18:10:22 UTC (rev 6)
+++ trunk/server/src/org/bedework/exchgsynch/ExchangeSubscription.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -1,261 +0,0 @@
-/* **********************************************************************
-    Copyright 2010 Rensselaer Polytechnic Institute. All worldwide rights reserved.
-
-    Redistribution and use of this distribution in source and binary forms,
-    with or without modification, are permitted provided that:
-       The above copyright notice and this permission notice appear in all
-        copies and supporting documentation;
-
-        The name, identifiers, and trademarks of Rensselaer Polytechnic
-        Institute are not used in advertising or publicity without the
-        express prior written permission of Rensselaer Polytechnic Institute;
-
-    DISCLAIMER: The software is distributed" AS IS" without any express or
-    implied warranty, including but not limited to, any implied warranties
-    of merchantability or fitness for a particular purpose or any warrant)'
-    of non-infringement of any current or pending patent rights. The authors
-    of the software make no representations about the suitability of this
-    software for any particular purpose. The entire risk as to the quality
-    and performance of the software is with the user. Should the software
-    prove defective, the user assumes the cost of all necessary servicing,
-    repair or correction. In particular, neither Rensselaer Polytechnic
-    Institute, nor the authors of the software are liable for any indirect,
-    special, consequential, or incidental damages related to the software,
-    to the maximum extent the law permits.
-*/
-
-package org.bedework.exchgsynch;
-
-import edu.rpi.cmt.access.AccessPrincipal;
-
-/** Represents a current subscription or a subscription request.
- *
- * @author Mike Douglass
- */
-public class ExchangeSubscription implements Comparable<ExchangeSubscription> {
-  private String calpath;
-
-  private AccessPrincipal principal;
-
-  private String exchangeCalendar;
-
-  private String exchangeURI;
-
-  private boolean subscribe;
-
-  private ExchangeSubscription outstandingSubscription;
-
-  /** Constructor
-   *
-   * @param principal
-   * @param calpath
-   * @param exchangeCalendar
-   * @param exchangeURI
-   * @param subscribe
-   */
-  public ExchangeSubscription(final String calpath,
-                              final AccessPrincipal principal,
-                              final String exchangeCalendar,
-                              final String exchangeURI,
-                              final boolean subscribe) {
-    this.principal = principal;
-    this.calpath = calpath;
-    this.exchangeCalendar = exchangeCalendar;
-    this.exchangeURI = exchangeURI;
-    this.subscribe = subscribe;
-  }
-
-  /** Path to this systems calendar collection
-   *
-   * @param val    String
-   */
-  public void setCalpath(final String val) {
-    calpath = val;
-  }
-
-  /** Path to this systems calendar collection
-   *
-   * @return String
-   */
-  public String getCalpath() {
-    return calpath;
-  }
-
-
-  /** Principal requesting synch service
-   *
-   * @param val    AccessPrincipal
-   */
-  public void setprincipal(final AccessPrincipal val) {
-    principal = val;
-  }
-
-  /** Principal requesting synch service
-   *
-   * @return AccessPrincipal
-   */
-  public AccessPrincipal getprincipal() {
-    return principal;
-  }
-  /** Exchange Calendar
-   *
-   * @param val    String
-   */
-  public void setExchangeCalendar(final String val) {
-    exchangeCalendar = val;
-  }
-
-  /** Exchange Calendar
-   *
-   * @return String
-   */
-  public String getExchangeCalendar() {
-    return exchangeCalendar;
-  }
-
-  /** Exchange web service uri
-   *
-   * @param val    String
-   */
-  public void setExchangeURI(final String val) {
-    exchangeURI = val;
-  }
-
-  /** Exchange web service uri
-   *
-   * @return String
-   */
-  public String getExchangeURI() {
-    return exchangeURI;
-  }
-
-  /** (un)subscribe?
-   *
-   * @param val    boolean
-   */
-  public void setSubscribe(final boolean val) {
-    subscribe = val;
-  }
-
-  /** (un)subscribe?
-   *
-   * @return boolean
-   */
-  public boolean getSubscribe() {
-    return subscribe;
-  }
-
-  /** An outstanding request that requires an unsubscribe to complete first
-   *
-   * @param val    ExchangeSubscription
-   */
-  public void setOutstandingSubscription(final ExchangeSubscription val) {
-    outstandingSubscription = val;
-  }
-
-  /** An outstanding request that requires an unsubscribe to complete first
-   *
-   * @return ExchangeSubscription
-   */
-  public ExchangeSubscription getOutstandingSubscription() {
-    return outstandingSubscription;
-  }
-
-  /** equality just checks the path. Look at the rest.
-   *
-   * @param that
-   * @return true if anything changed
-   */
-  public boolean changed(final ExchangeSubscription that) {
-    if (!equals(that)) {
-      return true;
-    }
-
-    if (!getprincipal().equals(that.getprincipal())) {
-      return true;
-    }
-
-    if (!getExchangeCalendar().equals(that.getExchangeCalendar())) {
-      return true;
-    }
-
-    if (!getExchangeURI().equals(that.getExchangeURI())) {
-      return true;
-    }
-
-    if (getSubscribe() != that.getSubscribe()) {
-      return true;
-    }
-
-    return false;
-  }
-
-  /* ====================================================================
-   *                        Object methods
-   * ==================================================================== */
-
-  @Override
-  public int hashCode() {
-    return getCalpath().hashCode();
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ExchangeSubscription{");
-
-    toStringSegment(sb, "  ");
-
-    if (getOutstandingSubscription() != null) {
-      sb.append(", \n  OustandingSubscription{");
-
-      toStringSegment(sb, "    ");
-      sb.append("  }");
-    }
-
-    sb.append("}");
-    return sb.toString();
-  }
-
-  /* (non-Javadoc)
-   * @see java.lang.Comparable#compareTo(java.lang.Object)
-   */
-  public int compareTo(final ExchangeSubscription that) {
-    if (this == that) {
-      return 0;
-    }
-
-    return getCalpath().compareTo(that.getCalpath());
-  }
-
-  @Override
-  public boolean equals(final Object o) {
-    return compareTo((ExchangeSubscription)o) == 0;
-  }
-
-  /* ====================================================================
-   *                        Private methods
-   * ==================================================================== */
-
-  private void toStringSegment(final StringBuilder sb,
-                              final String indent) {
-    sb.append("calpath = ");
-    sb.append(getCalpath());
-
-    sb.append(",\n");
-    sb.append(indent);
-    sb.append("principal = ");
-    sb.append(getprincipal());
-
-    sb.append(",\n");
-    sb.append(indent);
-    sb.append("exchangeCalendar = ");
-    sb.append(getExchangeCalendar());
-    sb.append(", exchangeURI = ");
-    sb.append(getExchangeURI());
-
-    sb.append(",\n");
-    sb.append(indent);
-    sb.append("subscribe = ");
-    sb.append(getSubscribe());
-  }
-}

Deleted: trunk/server/src/org/bedework/exchgsynch/ExchangeSynch.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/ExchangeSynch.java	2010-09-28 18:10:22 UTC (rev 6)
+++ trunk/server/src/org/bedework/exchgsynch/ExchangeSynch.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -1,284 +0,0 @@
-/* **********************************************************************
-    Copyright 2010 Rensselaer Polytechnic Institute. All worldwide rights reserved.
-
-    Redistribution and use of this distribution in source and binary forms,
-    with or without modification, are permitted provided that:
-       The above copyright notice and this permission notice appear in all
-        copies and supporting documentation;
-
-        The name, identifiers, and trademarks of Rensselaer Polytechnic
-        Institute are not used in advertising or publicity without the
-        express prior written permission of Rensselaer Polytechnic Institute;
-
-    DISCLAIMER: The software is distributed" AS IS" without any express or
-    implied warranty, including but not limited to, any implied warranties
-    of merchantability or fitness for a particular purpose or any warrant)'
-    of non-infringement of any current or pending patent rights. The authors
-    of the software make no representations about the suitability of this
-    software for any particular purpose. The entire risk as to the quality
-    and performance of the software is with the user. Should the software
-    prove defective, the user assumes the cost of all necessary servicing,
-    repair or correction. In particular, neither Rensselaer Polytechnic
-    Institute, nor the authors of the software are liable for any indirect,
-    special, consequential, or incidental damages related to the software,
-    to the maximum extent the law permits.
-*/
-
-package org.bedework.exchgsynch;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-/** Exchange synch processor.
- *
- * <p>This process manages the setting up of push-subscriptions with the exchange
- * service and provides support for the resulting call-back from Exchange.
- *
- * @author Mike Douglass
- */
-public class ExchangeSynch {
-  private boolean debug;
-
-  protected transient Logger log;
-
-  /* Map of subscription requests with our calendar path as key */
-  private Map<String, ExchangeSubscription> subs =
-    new HashMap<String, ExchangeSubscription>();
-
-  /* Map of subscription requests with Exchange subscription id as key */
-  private Map<String, ExchangeSubscription> subsById =
-    new HashMap<String, ExchangeSubscription>();
-
-  ///* Line up subscriptions for processing */
-  //private Queue<ExchangeSubscription> subscribeQueue =
-  //  new ConcurrentLinkedQueue<ExchangeSubscription>();
-
-  private ExchangeSynchIntf intf;
-
-  private ExchangeSynchIntf exintf;
-
-  private boolean starting;
-
-  private boolean running;
-
-  private boolean stopping;
-
-  /* Where we keep subscriptions that come in while we are starting */
-  private List<ExchangeSubscription> subsList;
-
-  private class Callback extends ExchangeCallback {
-    @Override
-    public void subscribeRequest(final ExchangeSubscription sub) throws SynchException {
-      ExchangeSynch.this.subscribeRequest(sub);
-    }
-  }
-
-  /* We use this as a monitor */
-  private Callback cb = new Callback();
-
-  /** Constructor
-   *
-   * @param intf
-   */
-  public ExchangeSynch(final ExchangeSynchIntf intf) {
-    this.intf = intf;
-    debug = getLogger().isDebugEnabled();
-  }
-
-  /** Start synch process.
-   *
-   * @throws SynchException
-   */
-  public void start() throws SynchException {
-    if (starting || running) {
-      warn("Start called when already starting or running");
-      return;
-    }
-
-    synchronized (cb) {
-      subsList = null;
-
-      starting = true;
-    }
-
-    if (!intf.initExchangeSynch(cb)) {
-      warn("System interface returned false from init. Stopping");
-      starting = false;
-      return;
-    }
-
-    info("**************************************************");
-    info("Starting exchange synch");
-    info("**************************************************");
-
-    /* Get the list of subscriptions from the back end service and process them.
-     * while starting, new subscribe requests get added to the list.
-     */
-    List<ExchangeSubscription> startList = exintf.getSubscriptions();
-
-    while (starting) {
-      if (debug) {
-        trace("startList has " + startList.size() + " subscriptions");
-      }
-
-      for (ExchangeSubscription es: startList) {
-        subscribe(es);
-      }
-
-      synchronized (cb) {
-        if (subsList == null) {
-          // Nothing came in as we started
-          starting = false;
-          running = true;
-          break;
-        }
-
-        startList = subsList;
-        subsList = null;
-      }
-    }
-
-    info("**************************************************");
-    info("Exchange synch started");
-    info("**************************************************");
-  }
-
-  /** Stop synch process.
-   *
-   * @throws SynchException
-   */
-  public void stop() throws SynchException {
-
-  }
-
-  /** Update or add a subscription.
-   *
-   * @param sub
-   * @throws SynchException
-   */
-  public void subscribeRequest(final ExchangeSubscription sub) throws SynchException {
-    if (debug) {
-      trace("new subscription " + sub);
-    }
-
-    synchronized (cb) {
-      if (starting) {
-        if (subsList == null) {
-          subsList = new ArrayList<ExchangeSubscription>();
-        }
-
-        subsList.add(sub);
-        return;
-      }
-    }
-
-    if (!running) {
-      return;
-    }
-
-    subscribe(sub);
-  }
-
-  /* ====================================================================
-   *                        private methods
-   * ==================================================================== */
-
-  private void subscribe(final ExchangeSubscription sub) throws SynchException {
-    if (debug) {
-      trace("Handle subscription " + sub);
-    }
-
-    if (!checkAccess(sub)) {
-      info("No access for subscription " + sub);
-      return;
-    }
-
-    synchronized (subs) {
-      ExchangeSubscription tsub = subs.get(sub.getCalpath());
-
-      if (tsub == null) {
-        if (!sub.getSubscribe()) {
-          if (debug) {
-            trace("Unsubscribe and already unsubscribed");
-          }
-        }
-
-        doSubscription(sub);
-        subs.put(sub.getCalpath(), sub);
-
-        return;
-      }
-
-      // We already have a subscription - does this change the state?
-      if (!tsub.changed(sub)) {
-        if (debug) {
-          trace("No change");
-        }
-
-        return;
-      }
-
-      if (tsub.getSubscribe() && !sub.getSubscribe()) {
-        // Unsubscribe request - set subscribed off and next callback will unsubscribe
-        tsub.setOutstandingSubscription(null);
-        tsub.setSubscribe(false);
-        return;
-      }
-
-      if (!tsub.getSubscribe() && sub.getSubscribe()) {
-        // Reverse previous unsubscribe?
-        tsub.setSubscribe(true);
-        return;
-      }
-
-      if (!tsub.getExchangeCalendar().equals(sub.getExchangeCalendar()) ||
-          !tsub.getExchangeURI().equals(sub.getExchangeURI())) {
-        // Pointing at another exchange target
-        tsub.setOutstandingSubscription(sub);
-        tsub.setSubscribe(false);
-        return;
-      }
-
-      return;
-    }
-
-
-  }
-
-  private void doSubscription(final ExchangeSubscription sub) throws SynchException {
-    /* Send a request for a new subscription to exchange */
-  }
-
-  private boolean checkAccess(final ExchangeSubscription sub) throws SynchException {
-    /* Does this principal have the rights to subscribe? */
-    return true;
-  }
-
-  private Logger getLogger() {
-    if (log == null) {
-      log = Logger.getLogger(this.getClass());
-    }
-
-    return log;
-  }
-
-  private void trace(final String msg) {
-    getLogger().debug(msg);
-  }
-
-  private void warn(final String msg) {
-    getLogger().warn(msg);
-  }
-
-  private void error(final Throwable t) {
-    getLogger().error(this, t);
-  }
-
-  private void info(final String msg) {
-    getLogger().info(msg);
-  }
-}

Deleted: trunk/server/src/org/bedework/exchgsynch/ExchangeSynchIntf.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/ExchangeSynchIntf.java	2010-09-28 18:10:22 UTC (rev 6)
+++ trunk/server/src/org/bedework/exchgsynch/ExchangeSynchIntf.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -1,79 +0,0 @@
-/* **********************************************************************
-    Copyright 2010 Rensselaer Polytechnic Institute. All worldwide rights reserved.
-
-    Redistribution and use of this distribution in source and binary forms,
-    with or without modification, are permitted provided that:
-       The above copyright notice and this permission notice appear in all
-        copies and supporting documentation;
-
-        The name, identifiers, and trademarks of Rensselaer Polytechnic
-        Institute are not used in advertising or publicity without the
-        express prior written permission of Rensselaer Polytechnic Institute;
-
-    DISCLAIMER: The software is distributed" AS IS" without any express or
-    implied warranty, including but not limited to, any implied warranties
-    of merchantability or fitness for a particular purpose or any warrant)'
-    of non-infringement of any current or pending patent rights. The authors
-    of the software make no representations about the suitability of this
-    software for any particular purpose. The entire risk as to the quality
-    and performance of the software is with the user. Should the software
-    prove defective, the user assumes the cost of all necessary servicing,
-    repair or correction. In particular, neither Rensselaer Polytechnic
-    Institute, nor the authors of the software are liable for any indirect,
-    special, consequential, or incidental damages related to the software,
-    to the maximum extent the law permits.
-*/
-
-package org.bedework.exchgsynch;
-
-import java.util.List;
-
-/** Calls from exchange synch processor to the service.
- *
- * @author Mike Douglass
- */
-public interface ExchangeSynchIntf {
-  /** Called to initialise the exchange synch process. A response of false means
-   * no exchange synch. Note that users can synchronize with exchange systems in
-   * other domains, so even if your site doesn't run exchange you may want to to
-   * run the synch process,
-   *
-   * @param cb
-   * @return false for no synch.
-   * @throws WebdavException
-   */
-  boolean initExchangeSynch(ExchangeCallback cb) throws SynchException;
-
-  /** */
-  public static class Credentials {
-    String id;
-    byte[] password;
-
-    /** Constructor
-     *
-     * @param id
-     * @param password
-     */
-    public Credentials(final String id,
-                       final byte[] password) {
-      this.id = id;
-      this.password = password;
-    }
-  }
-
-  /** Get Credentials allowing log in to exchange for the given subscription
-   *
-   * @param sub
-   * @return Credentials object
-   * @throws SynchException
-   */
-  Credentials getCredentials(ExchangeSubscription sub) throws SynchException;
-
-  /** Called by the Exchange synch process at startup to get the current list
-   * of subscriptions. Will normally not be called again.
-   *
-   * @return List of current subscriptions - never null
-   * @throws SynchException
-   */
-  List<ExchangeSubscription> getSubscriptions() throws SynchException;
-}

Deleted: trunk/server/src/org/bedework/exchgsynch/ExsynchConfig.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/ExsynchConfig.java	2010-09-28 18:10:22 UTC (rev 6)
+++ trunk/server/src/org/bedework/exchgsynch/ExsynchConfig.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -1,89 +0,0 @@
-/* **********************************************************************
-    Copyright 2007 Rensselaer Polytechnic Institute. All worldwide rights reserved.
-
-    Redistribution and use of this distribution in source and binary forms,
-    with or without modification, are permitted provided that:
-       The above copyright notice and this permission notice appear in all
-        copies and supporting documentation;
-
-        The name, identifiers, and trademarks of Rensselaer Polytechnic
-        Institute are not used in advertising or publicity without the
-        express prior written permission of Rensselaer Polytechnic Institute;
-
-    DISCLAIMER: The software is distributed" AS IS" without any express or
-    implied warranty, including but not limited to, any implied warranties
-    of merchantability or fitness for a particular purpose or any warrant)'
-    of non-infringement of any current or pending patent rights. The authors
-    of the software make no representations about the suitability of this
-    software for any particular purpose. The entire risk as to the quality
-    and performance of the software is with the user. Should the software
-    prove defective, the user assumes the cost of all necessary servicing,
-    repair or correction. In particular, neither Rensselaer Polytechnic
-    Institute, nor the authors of the software are liable for any indirect,
-    special, consequential, or incidental damages related to the software,
-    to the maximum extent the law permits.
-*/
-package org.bedework.exchgsynch;
-
-import java.io.Serializable;
-
-/** This class defines the various properties we need for an Exchange synch
- *
- * @author Mike Douglass
- */
-public class ExsynchConfig implements Serializable {
-  /* Fro bedework build */
-  private String appType;
-
-  /* Default exchange web service uri - null for no default */
-  private String exchangeWsURI;
-
-  /* Exchange web service push callback uri - null for no exchange sync */
-  private String exchangeWsPushURI;
-
-  /**
-   * @param val
-   */
-  public void setAppType(final String val) {
-    appType = val;
-  }
-
-  /**
-   * @return String
-   */
-  public String getAppType() {
-    return appType;
-  }
-
-  /** Default exchange web service uri - null for no default
-   *
-   * @param val    String
-   */
-  public void setExchangeWsURI(final String val) {
-    exchangeWsURI = val;
-  }
-
-  /** Default exchange web service uri - null for no default
-   *
-   * @return String
-   */
-  public String getExchangeWsURI() {
-    return exchangeWsURI;
-  }
-
-  /** Exchange web service push callback uri - null for no exchange sync
-   *
-   * @param val    String
-   */
-  public void setExchangeWsPushURI(final String val) {
-    exchangeWsPushURI = val;
-  }
-
-  /** Exchange web service push callback uri - null for no exchange sync
-   *
-   * @return String
-   */
-  public String getExchangeWsPushURI() {
-    return exchangeWsPushURI;
-  }
-}

Deleted: trunk/server/src/org/bedework/exchgsynch/SynchException.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/SynchException.java	2010-09-28 18:10:22 UTC (rev 6)
+++ trunk/server/src/org/bedework/exchgsynch/SynchException.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -1,126 +0,0 @@
-/* **********************************************************************
-    Copyright 2005 Rensselaer Polytechnic Institute. All worldwide rights reserved.
-
-    Redistribution and use of this distribution in source and binary forms,
-    with or without modification, are permitted provided that:
-       The above copyright notice and this permission notice appear in all
-        copies and supporting documentation;
-
-        The name, identifiers, and trademarks of Rensselaer Polytechnic
-        Institute are not used in advertising or publicity without the
-        express prior written permission of Rensselaer Polytechnic Institute;
-
-    DISCLAIMER: The software is distributed" AS IS" without any express or
-    implied warranty, including but not limited to, any implied warranties
-    of merchantability or fitness for a particular purpose or any warrant)'
-    of non-infringement of any current or pending patent rights. The authors
-    of the software make no representations about the suitability of this
-    software for any particular purpose. The entire risk as to the quality
-    and performance of the software is with the user. Should the software
-    prove defective, the user assumes the cost of all necessary servicing,
-    repair or correction. In particular, neither Rensselaer Polytechnic
-    Institute, nor the authors of the software are liable for any indirect,
-    special, consequential, or incidental damages related to the software,
-    to the maximum extent the law permits.
-*/
-
-package org.bedework.exchgsynch;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.namespace.QName;
-
-/** Base exception thrown by exchange synch classes
- *
- *   @author Mike Douglass   douglm at rpi.edu
- */
-public class SynchException extends Throwable {
-  /** > 0 if set
-   */
-  int statusCode = -1;
-  QName errorTag;
-
-  /** Constructor
-   *
-   * @param s
-   */
-  public SynchException(String s) {
-    super(s);
-    if (statusCode < 0) {
-      statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
-    }
-  }
-
-  /** Constructor
-   *
-   * @param t
-   */
-  public SynchException(Throwable t) {
-    super(t);
-    if (statusCode < 0) {
-      statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
-    }
-  }
-
-  /** Constructor
-   *
-   * @param st
-   */
-  public SynchException(int st) {
-    statusCode = st;
-  }
-
-  /** Constructor
-   *
-   * @param st
-   * @param msg
-   */
-  public SynchException(int st, String msg) {
-    super(msg);
-    statusCode = st;
-  }
-
-  /** Constructor
-   *
-   * @param st
-   * @param errorTag
-   */
-  public SynchException(int st, QName errorTag) {
-    statusCode = st;
-    this.errorTag = errorTag;
-  }
-
-  /** Constructor
-   *
-   * @param st
-   * @param errorTag
-   * @param msg
-   */
-  public SynchException(int st, QName errorTag, String msg) {
-    super(msg);
-    statusCode = st;
-    this.errorTag = errorTag;
-  }
-
-  /** Set the status
-   * @param val int status
-   */
-  public void setStatusCode(int val) {
-    statusCode = val;
-  }
-
-  /** Get the status
-   *
-   * @return int status
-   */
-  public int getStatusCode() {
-    return statusCode;
-  }
-
-  /** Get the errorTag
-   *
-   * @return QName
-   */
-  public QName getErrorTag() {
-    return errorTag;
-  }
-}

Added: trunk/server/src/org/bedework/exchgsynch/web/ExsynchServlet.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/web/ExsynchServlet.java	                        (rev 0)
+++ trunk/server/src/org/bedework/exchgsynch/web/ExsynchServlet.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -0,0 +1,460 @@
+/* **********************************************************************
+    Copyright 2005 Rensselaer Polytechnic Institute. All worldwide rights reserved.
+
+    Redistribution and use of this distribution in source and binary forms,
+    with or without modification, are permitted provided that:
+       The above copyright notice and this permission notice appear in all
+        copies and supporting documentation;
+
+        The name, identifiers, and trademarks of Rensselaer Polytechnic
+        Institute are not used in advertising or publicity without the
+        express prior written permission of Rensselaer Polytechnic Institute;
+
+    DISCLAIMER: The software is distributed" AS IS" without any express or
+    implied warranty, including but not limited to, any implied warranties
+    of merchantability or fitness for a particular purpose or any warrant)'
+    of non-infringement of any current or pending patent rights. The authors
+    of the software make no representations about the suitability of this
+    software for any particular purpose. The entire risk as to the quality
+    and performance of the software is with the user. Should the software
+    prove defective, the user assumes the cost of all necessary servicing,
+    repair or correction. In particular, neither Rensselaer Polytechnic
+    Institute, nor the authors of the software are liable for any indirect,
+    special, consequential, or incidental damages related to the software,
+    to the maximum extent the law permits.
+*/
+
+package org.bedework.exchgsynch.web;
+
+import org.bedework.exchgsynch.ExchangeSynch;
+import org.bedework.exchgsynch.SynchException;
+import org.bedework.exchgsynch.web.MethodBase.MethodInfo;
+
+import edu.rpi.sss.util.servlets.io.CharArrayWrappedResponse;
+import edu.rpi.sss.util.xml.XmlEmit;
+import edu.rpi.sss.util.xml.tagdefs.WebdavTags;
+
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.HashMap;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+import javax.xml.namespace.QName;
+
+/** WebDAV Servlet.
+ * This abstract servlet handles the request/response nonsense and calls
+ * abstract routines to interact with an underlying data source.
+ *
+ * @author Mike Douglass   douglm at rpi.edu
+ * @version 1.0
+ */
+public abstract class ExsynchServlet extends HttpServlet
+        implements HttpSessionListener {
+  protected boolean debug;
+
+  protected boolean dumpContent;
+
+  protected transient Logger log;
+
+  /** Table of methods - set at init
+   */
+  protected HashMap<String, MethodInfo> methods = new HashMap<String, MethodInfo>();
+
+  /* Try to serialize requests from a single session
+   * This is very imperfect.
+   */
+  static class Waiter {
+    boolean active;
+    int waiting;
+  }
+
+  private static volatile HashMap<String, Waiter> waiters = new HashMap<String, Waiter>();
+
+  @Override
+  public void init(final ServletConfig config) throws ServletException {
+    super.init(config);
+
+    dumpContent = "true".equals(config.getInitParameter("dumpContent"));
+
+    addMethods();
+  }
+
+  @Override
+  protected void service(final HttpServletRequest req,
+                         HttpServletResponse resp)
+      throws ServletException, IOException {
+    ExchangeSynch syncher = null;
+    boolean serverError = false;
+
+    try {
+      String debugStr = getInitParameter("debug");
+      if (debugStr != null) {
+        debug = !"0".equals(debugStr);
+      }
+
+      if (debug) {
+        debugMsg("entry: " + req.getMethod());
+        dumpRequest(req);
+      }
+
+      tryWait(req, true);
+
+      syncher = ExchangeSynch.getSyncher();
+
+      if (req.getCharacterEncoding() == null) {
+        req.setCharacterEncoding("UTF-8");
+        if (debug) {
+          debugMsg("No charset specified in request; forced to UTF-8");
+        }
+      }
+
+      if (debug && dumpContent) {
+        resp = new CharArrayWrappedResponse(resp,
+                                            getLogger(), debug);
+      }
+
+      String methodName = req.getHeader("X-HTTP-Method-Override");
+
+      if (methodName == null) {
+        methodName = req.getMethod();
+      }
+
+      MethodBase method = getMethod(methodName);
+
+      if (method == null) {
+        logIt("No method for '" + methodName + "'");
+
+        // ================================================================
+        //     Set the correct response
+        // ================================================================
+      } else {
+        method.doMethod(req, resp);
+      }
+//    } catch (WebdavForbidden wdf) {
+  //    sendError(syncher, wdf, resp);
+    } catch (Throwable t) {
+      serverError = handleException(syncher, t, resp, serverError);
+    } finally {
+      if (syncher != null) {
+        try {
+//          syncher.close();
+        } catch (Throwable t) {
+          serverError = handleException(syncher, t, resp, serverError);
+        }
+      }
+
+      try {
+        tryWait(req, false);
+      } catch (Throwable t) {}
+
+      if (debug && dumpContent &&
+          (resp instanceof CharArrayWrappedResponse)) {
+        /* instanceof check because we might get a subsequent exception before
+         * we wrap the response
+         */
+        CharArrayWrappedResponse wresp = (CharArrayWrappedResponse)resp;
+
+        if (wresp.getUsedOutputStream()) {
+          debugMsg("------------------------ response written to output stream -------------------");
+        } else {
+          String str = wresp.toString();
+
+          debugMsg("------------------------ Dump of response -------------------");
+          debugMsg(str);
+          debugMsg("---------------------- End dump of response -----------------");
+
+          byte[] bs = str.getBytes();
+          resp = (HttpServletResponse)wresp.getResponse();
+          debugMsg("contentLength=" + bs.length);
+          resp.setContentLength(bs.length);
+          resp.getOutputStream().write(bs);
+        }
+      }
+
+      /* WebDAV is stateless - toss away the session */
+      try {
+        HttpSession sess = req.getSession(false);
+        if (sess != null) {
+          sess.invalidate();
+        }
+      } catch (Throwable t) {}
+    }
+  }
+
+  /* Return true if it's a server error */
+  private boolean handleException(final ExchangeSynch syncher, final Throwable t,
+                                  final HttpServletResponse resp,
+                                  boolean serverError) {
+    if (serverError) {
+      return true;
+    }
+
+    try {
+      if (t instanceof SynchException) {
+        SynchException se = (SynchException)t;
+
+        int status = se.getStatusCode();
+        if (status == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
+          getLogger().error(this, se);
+          serverError = true;
+        }
+        sendError(syncher, t, resp);
+        return serverError;
+      }
+
+      getLogger().error(this, t);
+      sendError(syncher, t, resp);
+      return true;
+    } catch (Throwable t1) {
+      // Pretty much screwed if we get here
+      return true;
+    }
+  }
+
+  private void sendError(final ExchangeSynch syncher, final Throwable t,
+                         final HttpServletResponse resp) {
+    try {
+      if (t instanceof SynchException) {
+        SynchException se = (SynchException)t;
+        QName errorTag = se.getErrorTag();
+
+        if (errorTag != null) {
+          if (debug) {
+            debugMsg("setStatus(" + se.getStatusCode() + ")");
+          }
+          resp.setStatus(se.getStatusCode());
+          resp.setContentType("text/xml; charset=UTF-8");
+          if (!emitError(syncher, errorTag, se.getMessage(),
+                         resp.getWriter())) {
+            StringWriter sw = new StringWriter();
+            emitError(syncher, errorTag, se.getMessage(), sw);
+
+            try {
+              if (debug) {
+                debugMsg("setStatus(" + se.getStatusCode() + ")");
+              }
+              resp.sendError(se.getStatusCode(), sw.toString());
+            } catch (Throwable t1) {
+            }
+          }
+        } else {
+          if (debug) {
+            debugMsg("setStatus(" + se.getStatusCode() + ")");
+          }
+          resp.sendError(se.getStatusCode(), se.getMessage());
+        }
+      } else {
+        if (debug) {
+          debugMsg("setStatus(" + HttpServletResponse.SC_INTERNAL_SERVER_ERROR + ")");
+        }
+        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                       t.getMessage());
+      }
+    } catch (Throwable t1) {
+      // Pretty much screwed if we get here
+    }
+  }
+
+  private boolean emitError(final ExchangeSynch syncher,
+                            final QName errorTag,
+                            final String extra,
+                            final Writer wtr) {
+    try {
+      XmlEmit xml = new XmlEmit();
+//      syncher.addNamespace(xml);
+
+      xml.startEmit(wtr);
+      xml.openTag(WebdavTags.error);
+
+  //    syncher.emitError(errorTag, extra, xml);
+
+      xml.closeTag(WebdavTags.error);
+      xml.flush();
+
+      return true;
+    } catch (Throwable t1) {
+      // Pretty much screwed if we get here
+      return false;
+    }
+  }
+
+  /** Add methods for this namespace
+   *
+   */
+  protected void addMethods() {
+    /*
+    methods.put("ACL", new MethodInfo(AclMethod.class, false));
+    methods.put("COPY", new MethodInfo(CopyMethod.class, false));
+    methods.put("GET", new MethodInfo(GetMethod.class, false));
+    methods.put("HEAD", new MethodInfo(HeadMethod.class, false));
+    methods.put("OPTIONS", new MethodInfo(OptionsMethod.class, false));
+    methods.put("PROPFIND", new MethodInfo(PropFindMethod.class, false));
+
+    methods.put("DELETE", new MethodInfo(DeleteMethod.class, true));
+    methods.put("MKCOL", new MethodInfo(MkcolMethod.class, true));
+    methods.put("MOVE", new MethodInfo(MoveMethod.class, true));
+    methods.put("POST", new MethodInfo(PostMethod.class, true));
+    methods.put("PROPPATCH", new MethodInfo(PropPatchMethod.class, true));
+    methods.put("PUT", new MethodInfo(PutMethod.class, true));
+    */
+
+    //methods.put("LOCK", new MethodInfo(LockMethod.class, true));
+    //methods.put("UNLOCK", new MethodInfo(UnlockMethod.class, true));
+  }
+
+  public static MethodBase getMethod(final String name) throws SynchException {
+    return null;
+  }
+
+  private void tryWait(final HttpServletRequest req, final boolean in) throws Throwable {
+    Waiter wtr = null;
+    synchronized (waiters) {
+      //String key = req.getRequestedSessionId();
+      String key = req.getRemoteUser();
+      if (key == null) {
+        return;
+      }
+
+      wtr = waiters.get(key);
+      if (wtr == null) {
+        if (!in) {
+          return;
+        }
+
+        wtr = new Waiter();
+        wtr.active = true;
+        waiters.put(key, wtr);
+        return;
+      }
+    }
+
+    synchronized (wtr) {
+      if (!in) {
+        wtr.active = false;
+        wtr.notify();
+        return;
+      }
+
+      wtr.waiting++;
+      while (wtr.active) {
+        if (debug) {
+          log.debug("in: waiters=" + wtr.waiting);
+        }
+
+        wtr.wait();
+      }
+      wtr.waiting--;
+      wtr.active = true;
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
+   */
+  public void sessionCreated(final HttpSessionEvent se) {
+  }
+
+  /* (non-Javadoc)
+   * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
+   */
+  public void sessionDestroyed(final HttpSessionEvent se) {
+    HttpSession session = se.getSession();
+    String sessid = session.getId();
+    if (sessid == null) {
+      return;
+    }
+
+    synchronized (waiters) {
+      waiters.remove(sessid);
+    }
+  }
+
+  /** Debug
+   *
+   * @param req
+   */
+  public void dumpRequest(final HttpServletRequest req) {
+    Logger log = getLogger();
+
+    try {
+      Enumeration names = req.getHeaderNames();
+
+      String title = "Request headers";
+
+      log.debug(title);
+
+      while (names.hasMoreElements()) {
+        String key = (String)names.nextElement();
+        String val = req.getHeader(key);
+        log.debug("  " + key + " = \"" + val + "\"");
+      }
+
+      names = req.getParameterNames();
+
+      title = "Request parameters";
+
+      log.debug(title + " - global info and uris");
+      log.debug("getRemoteAddr = " + req.getRemoteAddr());
+      log.debug("getRequestURI = " + req.getRequestURI());
+      log.debug("getRemoteUser = " + req.getRemoteUser());
+      log.debug("getRequestedSessionId = " + req.getRequestedSessionId());
+      log.debug("HttpUtils.getRequestURL(req) = " + req.getRequestURL());
+      log.debug("contextPath=" + req.getContextPath());
+      log.debug("query=" + req.getQueryString());
+      log.debug("contentlen=" + req.getContentLength());
+      log.debug("request=" + req);
+      log.debug("parameters:");
+
+      log.debug(title);
+
+      while (names.hasMoreElements()) {
+        String key = (String)names.nextElement();
+        String val = req.getParameter(key);
+        log.debug("  " + key + " = \"" + val + "\"");
+      }
+    } catch (Throwable t) {
+    }
+  }
+
+  /**
+   * @return LOgger
+   */
+  public Logger getLogger() {
+    if (log == null) {
+      log = Logger.getLogger(this.getClass());
+    }
+
+    return log;
+  }
+
+  /** Debug
+   *
+   * @param msg
+   */
+  public void debugMsg(final String msg) {
+    getLogger().debug(msg);
+  }
+
+  /** Info messages
+   *
+   * @param msg
+   */
+  public void logIt(final String msg) {
+    getLogger().info(msg);
+  }
+
+  protected void error(final Throwable t) {
+    getLogger().error(this, t);
+  }
+}

Added: trunk/server/src/org/bedework/exchgsynch/web/MethodBase.java
===================================================================
--- trunk/server/src/org/bedework/exchgsynch/web/MethodBase.java	                        (rev 0)
+++ trunk/server/src/org/bedework/exchgsynch/web/MethodBase.java	2010-09-28 18:10:32 UTC (rev 7)
@@ -0,0 +1,506 @@
+/* **********************************************************************
+    Copyright 2005 Rensselaer Polytechnic Institute. All worldwide rights reserved.
+
+    Redistribution and use of this distribution in source and binary forms,
+    with or without modification, are permitted provided that:
+       The above copyright notice and this permission notice appear in all
+        copies and supporting documentation;
+
+        The name, identifiers, and trademarks of Rensselaer Polytechnic
+        Institute are not used in advertising or publicity without the
+        express prior written permission of Rensselaer Polytechnic Institute;
+
+    DISCLAIMER: The software is distributed" AS IS" without any express or
+    implied warranty, including but not limited to, any implied warranties
+    of merchantability or fitness for a particular purpose or any warrant)'
+    of non-infringement of any current or pending patent rights. The authors
+    of the software make no representations about the suitability of this
+    software for any particular purpose. The entire risk as to the quality
+    and performance of the software is with the user. Should the software
+    prove defective, the user assumes the cost of all necessary servicing,
+    repair or correction. In particular, neither Rensselaer Polytechnic
+    Institute, nor the authors of the software are liable for any indirect,
+    special, consequential, or incidental damages related to the software,
+    to the maximum extent the law permits.
+*/
+
+package org.bedework.exchgsynch.web;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.log4j.Logger;
+import org.bedework.exchgsynch.ExchangeSynch;
+import org.bedework.exchgsynch.SynchBadRequest;
+import org.bedework.exchgsynch.SynchException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import edu.rpi.sss.util.xml.XmlEmit;
+import edu.rpi.sss.util.xml.XmlUtil;
+import edu.rpi.sss.util.xml.XmlEmit.NameSpace;
+import edu.rpi.sss.util.xml.tagdefs.WebdavTags;
+
+/** Base class for all webdav servlet methods.
+ */
+public abstract class MethodBase {
+  protected boolean debug;
+
+  protected boolean dumpContent;
+
+  protected transient Logger log;
+
+  protected ExchangeSynch syncher;
+
+  private String resourceUri;
+
+  // private String content;
+
+  protected XmlEmit xml;
+
+  /** Called at each request
+   */
+  public abstract void init();
+
+  private SimpleDateFormat httpDateFormatter =
+      new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss ");
+
+  /**
+   * @param req
+   * @param resp
+   * @throws WebdavException
+   */
+  public abstract void doMethod(HttpServletRequest req,
+                                HttpServletResponse resp)
+        throws SynchException;
+
+  /** Allow servlet to create method.
+   */
+  public static class MethodInfo {
+    private Class methodClass;
+
+    private boolean requiresAuth;
+
+    /**
+     * @param methodClass
+     * @param requiresAuth
+     */
+    public MethodInfo(final Class methodClass, final boolean requiresAuth) {
+      this.methodClass = methodClass;
+      this.requiresAuth = requiresAuth;
+    }
+
+    /**
+     * @return Class for this method
+     */
+    public Class getMethodClass() {
+      return methodClass;
+    }
+
+    /** Called when servicing a request to determine if this method requires
+     * authentication. Allows the servlet to reject attempts to change state
+     * while unauthenticated.
+     *
+     * @return boolean true if authentication required.
+     */
+    public boolean getRequiresAuth() {
+      return requiresAuth;
+    }
+  }
+
+  /** Called at each request
+   *
+   * @param nsIntf
+   * @param debug
+   * @param dumpContent
+   * @throws WebdavException
+   */
+  public void init(final ExchangeSynch syncher,
+                   final boolean debug,
+                   final boolean dumpContent) throws SynchException {
+    this.syncher = syncher;
+    this.debug = debug;
+    this.dumpContent = dumpContent;
+
+//    xml = syncher.getXmlEmit();
+
+    // content = null;
+    resourceUri = null;
+
+    init();
+  }
+
+  /** Get syncher
+   *
+   * @return ExchangeSynch
+   */
+  public ExchangeSynch getSyncher() {
+    return syncher;
+  }
+
+  /** Get the decoded and fixed resource URI
+   *
+   * @param req      Servlet request object
+   * @return String  fixed up uri
+   * @throws WebdavException
+   */
+  public String getResourceUri(final HttpServletRequest req)
+      throws SynchException {
+    if (resourceUri != null) {
+      return resourceUri;
+    }
+
+    /*
+    resourceUri = WebdavNsIntf.getResourceUri(req);
+
+    if (debug) {
+      trace("resourceUri: " + resourceUri);
+    }
+
+    return resourceUri;*/
+    return null;
+  }
+
+  protected void addStatus(final int status, final String message) throws SynchException {
+    try {
+      if (message == null) {
+//        message = WebdavStatusCode.getMessage(status);
+      }
+
+      property(WebdavTags.status, "HTTP/1.1 " + status + " " + message);
+    } catch (SynchException wde) {
+      throw wde;
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  protected void addHeaders(final HttpServletResponse resp) throws SynchException {
+    // This probably needs changes
+/*
+    StringBuilder methods = new StringBuilder();
+    for (String name: getSyncher().getMethodNames()) {
+      if (methods.length() > 0) {
+        methods.append(", ");
+      }
+
+      methods.append(name);
+    }
+
+    resp.addHeader("Allow", methods.toString());
+    */
+    resp.addHeader("Allow", "POST, GET");
+  }
+
+  /** Parse the request body, and return the DOM representation.
+   *
+   * @param req        Servlet request object
+   * @param resp       Servlet response object for bad status
+   * @return Document  Parsed body or null for no body
+   * @exception WebdavException Some error occurred.
+   */
+  protected Document parseContent(final HttpServletRequest req,
+                                  final HttpServletResponse resp)
+      throws SynchException{
+    int len = req.getContentLength();
+    if (len == 0) {
+      return null;
+    }
+
+    try {
+      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+      factory.setNamespaceAware(true);
+
+      DocumentBuilder builder = factory.newDocumentBuilder();
+/*
+      Reader rdr = getNsIntf().getReader(req);
+
+      if (rdr == null) {
+        // No content?
+        return null;
+      }
+
+      return builder.parse(new InputSource(rdr));*/
+      return null;
+//    } catch (SAXException e) {
+  //    resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+    //  throw new SynchException(HttpServletResponse.SC_BAD_REQUEST);
+    } catch (Throwable t) {
+      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+      throw new SynchException(t);
+    }
+  }
+
+  protected String formatHTTPDate(final Timestamp val) {
+    if (val == null) {
+      return null;
+    }
+
+    synchronized (httpDateFormatter) {
+      return httpDateFormatter.format(val) + "GMT";
+    }
+  }
+
+  /* ====================================================================
+   *                   XmlUtil wrappers
+   * ==================================================================== */
+
+  protected Collection<Element> getChildren(final Node nd) throws SynchException {
+    try {
+      return XmlUtil.getElements(nd);
+    } catch (Throwable t) {
+      if (debug) {
+        getLogger().error(this, t);
+      }
+
+      throw new SynchBadRequest(t.getMessage());
+    }
+  }
+
+  protected Element[] getChildrenArray(final Node nd) throws SynchException {
+    try {
+      return XmlUtil.getElementsArray(nd);
+    } catch (Throwable t) {
+      if (debug) {
+        getLogger().error(this, t);
+      }
+
+      throw new SynchBadRequest(t.getMessage());
+    }
+  }
+
+  protected Element getOnlyChild(final Node nd) throws SynchException {
+    try {
+      return XmlUtil.getOnlyElement(nd);
+    } catch (Throwable t) {
+      if (debug) {
+        getLogger().error(this, t);
+      }
+
+      throw new SynchBadRequest(t.getMessage());
+    }
+  }
+
+  protected String getElementContent(final Element el) throws SynchException {
+    try {
+      return XmlUtil.getElementContent(el);
+    } catch (Throwable t) {
+      if (debug) {
+        getLogger().error(this, t);
+      }
+
+      throw new SynchBadRequest(t.getMessage());
+    }
+  }
+
+  protected boolean isEmpty(final Element el) throws SynchException {
+    try {
+      return XmlUtil.isEmpty(el);
+    } catch (Throwable t) {
+      if (debug) {
+        getLogger().error(this, t);
+      }
+
+      throw new SynchBadRequest(t.getMessage());
+    }
+  }
+
+  /* ====================================================================
+   *                   XmlEmit wrappers
+   * ==================================================================== */
+
+  protected void startEmit(final HttpServletResponse resp) throws SynchException {
+    try {
+      xml.startEmit(resp.getWriter());
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** Add a namespace
+   *
+   * @param val
+   * @throws SynchException
+   */
+  public void addNs(final String val) throws SynchException {
+    if (xml.getNameSpace(val) == null) {
+      try {
+        xml.addNs(new NameSpace(val, null), false);
+      } catch (IOException e) {
+        throw new SynchException(e);
+      }
+    }
+  }
+
+  /** Get a namespace abbreviation
+   *
+   * @param ns namespace
+   * @return String abbrev
+   */
+  public String getNsAbbrev(final String ns) {
+    return xml.getNsAbbrev(ns);
+  }
+
+  protected void openTag(final QName tag) throws SynchException {
+    try {
+      xml.openTag(tag);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  protected void openTagNoNewline(final QName tag) throws SynchException {
+    try {
+      xml.openTagNoNewline(tag);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  protected void closeTag(final QName tag) throws SynchException {
+    try {
+      xml.closeTag(tag);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** Emit an empty tag
+   *
+   * @param tag
+   * @throws SynchException
+   */
+  public void emptyTag(final QName tag) throws SynchException {
+    try {
+      xml.emptyTag(tag);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** Emit an empty tag corresponding to a node
+  *
+  * @param nd
+  * @throws SynchException
+  */
+  public void emptyTag(final Node nd) throws SynchException {
+    String ns = nd.getNamespaceURI();
+    String ln = nd.getLocalName();
+
+    emptyTag(new QName(ns, ln));
+  }
+
+  /** Emit a property
+   *
+   * @param tag
+   * @param val
+   * @throws SynchException
+   */
+  public void property(final QName tag, final String val) throws SynchException {
+    try {
+      xml.property(tag, val);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** Emit a property
+   *
+   * @param tag
+   * @param val
+   * @throws SynchException
+   */
+  public void cdataProperty(final QName tag, final String val) throws SynchException {
+    try {
+      xml.cdataProperty(tag, val);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** Emit a property
+   *
+   * @param tag
+   * @param val
+   * @throws SynchException
+   */
+  public void property(final QName tag, final Reader val) throws SynchException {
+    try {
+      xml.property(tag, val);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** Emit a property
+  *
+   * @param tag
+   * @param tagVal
+   * @throws SynchException
+   */
+  public void propertyTagVal(final QName tag, final QName tagVal) throws SynchException {
+    try {
+      xml.propertyTagVal(tag, tagVal);
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  protected void flush() throws SynchException {
+    try {
+      xml.flush();
+    } catch (Throwable t) {
+      throw new SynchException(t);
+    }
+  }
+
+  /** ===================================================================
+   *                   Logging methods
+   *  =================================================================== */
+
+  /**
+   * @return Logger
+   */
+  protected Logger getLogger() {
+    if (log == null) {
+      log = Logger.getLogger(this.getClass());
+    }
+
+    return log;
+  }
+
+  protected void debugMsg(final String msg) {
+    getLogger().debug(msg);
+  }
+
+  protected void error(final Throwable t) {
+    getLogger().error(this, t);
+  }
+
+  protected void error(final String msg) {
+    getLogger().error(msg);
+  }
+
+  protected void warn(final String msg) {
+    getLogger().warn(msg);
+  }
+
+  protected void logIt(final String msg) {
+    getLogger().info(msg);
+  }
+
+  protected void trace(final String msg) {
+    getLogger().debug(msg);
+  }
+}
+



More information about the Bedework-commit mailing list