[Bedework-commit] rpiutil r256 - in trunk/src/edu/rpi: cmt/calendar cmt/db/hibernate sss/util sss/util/xml/tagdefs

svnadmin at bedework.org svnadmin at bedework.org
Tue Aug 23 15:42:25 EDT 2011


Author: douglm
Date: 2011-08-23 15:42:24 -0400 (Tue, 23 Aug 2011)
New Revision: 256

Added:
   trunk/src/edu/rpi/cmt/calendar/IcalToXcal.java
   trunk/src/edu/rpi/cmt/db/hibernate/GenericEnumUserType.java
Modified:
   trunk/src/edu/rpi/cmt/calendar/PropertyIndex.java
   trunk/src/edu/rpi/sss/util/Util.java
   trunk/src/edu/rpi/sss/util/xml/tagdefs/XcalTags.java
Log:
added a file connector to synch 

ical4j to xml conversion added to rpiutil.

Added: trunk/src/edu/rpi/cmt/calendar/IcalToXcal.java
===================================================================
--- trunk/src/edu/rpi/cmt/calendar/IcalToXcal.java	                        (rev 0)
+++ trunk/src/edu/rpi/cmt/calendar/IcalToXcal.java	2011-08-23 19:42:24 UTC (rev 256)
@@ -0,0 +1,1135 @@
+/* ********************************************************************
+    Licensed to Jasig under one or more contributor license
+    agreements. See the NOTICE file distributed with this work
+    for additional information regarding copyright ownership.
+    Jasig licenses this file to you under the Apache License,
+    Version 2.0 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a
+    copy of the License at:
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on
+    an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied. See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+package edu.rpi.cmt.calendar;
+
+import edu.rpi.cmt.calendar.PropertyIndex.PropertyInfoIndex;
+import edu.rpi.sss.util.Util;
+
+import net.fortuna.ical4j.model.Calendar;
+import net.fortuna.ical4j.model.CategoryList;
+import net.fortuna.ical4j.model.ComponentList;
+import net.fortuna.ical4j.model.Date;
+import net.fortuna.ical4j.model.NumberList;
+import net.fortuna.ical4j.model.Parameter;
+import net.fortuna.ical4j.model.Period;
+import net.fortuna.ical4j.model.PeriodList;
+import net.fortuna.ical4j.model.Property;
+import net.fortuna.ical4j.model.PropertyList;
+import net.fortuna.ical4j.model.Recur;
+import net.fortuna.ical4j.model.ResourceList;
+import net.fortuna.ical4j.model.WeekDay;
+import net.fortuna.ical4j.model.component.CalendarComponent;
+import net.fortuna.ical4j.model.component.VAlarm;
+import net.fortuna.ical4j.model.component.VEvent;
+import net.fortuna.ical4j.model.component.VFreeBusy;
+import net.fortuna.ical4j.model.component.VJournal;
+import net.fortuna.ical4j.model.component.VToDo;
+import net.fortuna.ical4j.model.parameter.Language;
+import net.fortuna.ical4j.model.parameter.Rsvp;
+import net.fortuna.ical4j.model.parameter.TzId;
+import net.fortuna.ical4j.model.parameter.Value;
+import net.fortuna.ical4j.model.property.Attendee;
+import net.fortuna.ical4j.model.property.Categories;
+import net.fortuna.ical4j.model.property.FreeBusy;
+import net.fortuna.ical4j.model.property.Geo;
+import net.fortuna.ical4j.model.property.Organizer;
+import net.fortuna.ical4j.model.property.PercentComplete;
+import net.fortuna.ical4j.model.property.Priority;
+import net.fortuna.ical4j.model.property.RRule;
+import net.fortuna.ical4j.model.property.Repeat;
+import net.fortuna.ical4j.model.property.Resources;
+import net.fortuna.ical4j.model.property.Sequence;
+import net.fortuna.ical4j.model.property.XProperty;
+
+import ietf.params.xml.ns.icalendar_2.ActionPropType;
+import ietf.params.xml.ns.icalendar_2.AltrepParamType;
+import ietf.params.xml.ns.icalendar_2.ArrayOfEventTodoContainedComponents;
+import ietf.params.xml.ns.icalendar_2.ArrayOfParameters;
+import ietf.params.xml.ns.icalendar_2.ArrayOfProperties;
+import ietf.params.xml.ns.icalendar_2.ArrayOfVcalendarContainedComponents;
+import ietf.params.xml.ns.icalendar_2.AttendeePropType;
+import ietf.params.xml.ns.icalendar_2.BaseComponentType;
+import ietf.params.xml.ns.icalendar_2.BaseParameterType;
+import ietf.params.xml.ns.icalendar_2.BasePropertyType;
+import ietf.params.xml.ns.icalendar_2.CategoriesPropType;
+import ietf.params.xml.ns.icalendar_2.ClassPropType;
+import ietf.params.xml.ns.icalendar_2.CnParamType;
+import ietf.params.xml.ns.icalendar_2.CommentPropType;
+import ietf.params.xml.ns.icalendar_2.CompletedPropType;
+import ietf.params.xml.ns.icalendar_2.ContactPropType;
+import ietf.params.xml.ns.icalendar_2.CreatedPropType;
+import ietf.params.xml.ns.icalendar_2.CutypeParamType;
+import ietf.params.xml.ns.icalendar_2.DateDatetimePropertyType;
+import ietf.params.xml.ns.icalendar_2.DelegatedFromParamType;
+import ietf.params.xml.ns.icalendar_2.DelegatedToParamType;
+import ietf.params.xml.ns.icalendar_2.DescriptionPropType;
+import ietf.params.xml.ns.icalendar_2.DirParamType;
+import ietf.params.xml.ns.icalendar_2.DtendPropType;
+import ietf.params.xml.ns.icalendar_2.DtstampPropType;
+import ietf.params.xml.ns.icalendar_2.DtstartPropType;
+import ietf.params.xml.ns.icalendar_2.DuePropType;
+import ietf.params.xml.ns.icalendar_2.DurationPropType;
+import ietf.params.xml.ns.icalendar_2.EventTodoComponentType;
+import ietf.params.xml.ns.icalendar_2.ExrulePropType;
+import ietf.params.xml.ns.icalendar_2.FbtypeParamType;
+import ietf.params.xml.ns.icalendar_2.FreebusyPropType;
+import ietf.params.xml.ns.icalendar_2.FreqRecurType;
+import ietf.params.xml.ns.icalendar_2.GeoPropType;
+import ietf.params.xml.ns.icalendar_2.IcalendarType;
+import ietf.params.xml.ns.icalendar_2.LanguageParamType;
+import ietf.params.xml.ns.icalendar_2.LastModifiedPropType;
+import ietf.params.xml.ns.icalendar_2.LocationPropType;
+import ietf.params.xml.ns.icalendar_2.MemberParamType;
+import ietf.params.xml.ns.icalendar_2.MethodPropType;
+import ietf.params.xml.ns.icalendar_2.ObjectFactory;
+import ietf.params.xml.ns.icalendar_2.OrganizerPropType;
+import ietf.params.xml.ns.icalendar_2.PartstatParamType;
+import ietf.params.xml.ns.icalendar_2.PercentCompletePropType;
+import ietf.params.xml.ns.icalendar_2.PeriodType;
+import ietf.params.xml.ns.icalendar_2.PriorityPropType;
+import ietf.params.xml.ns.icalendar_2.ProdidPropType;
+import ietf.params.xml.ns.icalendar_2.RecurType;
+import ietf.params.xml.ns.icalendar_2.RecurrenceIdPropType;
+import ietf.params.xml.ns.icalendar_2.RelatedParamType;
+import ietf.params.xml.ns.icalendar_2.RelatedToPropType;
+import ietf.params.xml.ns.icalendar_2.ReltypeParamType;
+import ietf.params.xml.ns.icalendar_2.RepeatPropType;
+import ietf.params.xml.ns.icalendar_2.ResourcesPropType;
+import ietf.params.xml.ns.icalendar_2.RoleParamType;
+import ietf.params.xml.ns.icalendar_2.RrulePropType;
+import ietf.params.xml.ns.icalendar_2.RsvpParamType;
+import ietf.params.xml.ns.icalendar_2.ScheduleStatusParamType;
+import ietf.params.xml.ns.icalendar_2.SentByParamType;
+import ietf.params.xml.ns.icalendar_2.SequencePropType;
+import ietf.params.xml.ns.icalendar_2.StatusPropType;
+import ietf.params.xml.ns.icalendar_2.SummaryPropType;
+import ietf.params.xml.ns.icalendar_2.TranspPropType;
+import ietf.params.xml.ns.icalendar_2.TriggerPropType;
+import ietf.params.xml.ns.icalendar_2.TzidParamType;
+import ietf.params.xml.ns.icalendar_2.UidPropType;
+import ietf.params.xml.ns.icalendar_2.UntilRecurType;
+import ietf.params.xml.ns.icalendar_2.UrlPropType;
+import ietf.params.xml.ns.icalendar_2.ValarmType;
+import ietf.params.xml.ns.icalendar_2.VcalendarType;
+import ietf.params.xml.ns.icalendar_2.VersionPropType;
+import ietf.params.xml.ns.icalendar_2.VeventType;
+import ietf.params.xml.ns.icalendar_2.VfreebusyType;
+import ietf.params.xml.ns.icalendar_2.VjournalType;
+import ietf.params.xml.ns.icalendar_2.VtodoType;
+import ietf.params.xml.ns.icalendar_2.XBedeworkCostPropType;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.JAXBElement;
+
+/** Conversion to XML from ical4j
+ * @author douglm
+ */
+public class IcalToXcal {
+  static ObjectFactory of = new ObjectFactory();
+
+  /**
+   * @param cal
+   * @param pattern - allows specification of a subset to be returned.
+   * @return icalendar in XML
+   * @throws Throwable
+   */
+  @SuppressWarnings("unchecked")
+  public static IcalendarType fromIcal(final Calendar cal,
+                                       final BaseComponentType pattern) throws Throwable {
+    IcalendarType ical = new IcalendarType();
+    VcalendarType vcal = new VcalendarType();
+
+    ical.getVcalendar().add(vcal);
+
+    processProperties(cal.getProperties(), vcal, pattern);
+
+    ComponentList icComps = cal.getComponents();
+
+    if (icComps == null) {
+      return ical;
+    }
+
+    ArrayOfVcalendarContainedComponents aoc = new ArrayOfVcalendarContainedComponents();
+    vcal.setComponents(aoc);
+
+    for (Object o: icComps) {
+      aoc.getVcalendarContainedComponent().add(toComponent((CalendarComponent)o,
+                                                           pattern));
+    }
+
+    return ical;
+  }
+
+  /** Make a BaseComponentType component from an ical4j object. This may produce a
+   * VEvent, VTodo or VJournal.
+   *
+   * @param val
+   * @param pattern - if non-null limit returned components and values to those
+   *                  supplied in the pattern.
+   * @return JAXBElement<? extends BaseComponentType>
+   * @throws Throwable
+   */
+  public static JAXBElement
+                    toComponent(final CalendarComponent val,
+                                final BaseComponentType pattern) throws Throwable {
+    if (val == null) {
+      return null;
+    }
+
+    PropertyList icprops = val.getProperties();
+    ComponentList icComps = null;
+
+    if (icprops == null) {
+      // Empty component
+      return null;
+    }
+
+    JAXBElement el;
+
+    if (val instanceof VEvent) {
+      el = of.createVevent(new VeventType());
+      icComps = ((VEvent)val).getAlarms();
+    } else if (val instanceof VToDo) {
+      el = of.createVtodo(new VtodoType());
+      icComps = ((VToDo)val).getAlarms();
+    } else if (val instanceof VJournal) {
+      el = of.createVjournal(new VjournalType());
+    } else if (val instanceof VFreeBusy) {
+      el = of.createVfreebusy(new VfreebusyType());
+    } else if (val instanceof VAlarm) {
+      el = of.createValarm(new ValarmType());
+    } else {
+      throw new Exception("org.bedework.invalid.entity.type" +
+          val.getClass().getName());
+    }
+
+    BaseComponentType comp = (BaseComponentType)el.getValue();
+
+    processProperties(val.getProperties(), comp, pattern);
+
+    if (Util.isEmpty(icComps)) {
+      return el;
+    }
+
+    if (comp instanceof EventTodoComponentType) {
+      /* Process any sub-components */
+      ArrayOfEventTodoContainedComponents aetcc =
+          new ArrayOfEventTodoContainedComponents();
+      ((EventTodoComponentType)comp).setComponents(aetcc);
+
+      for (Object o: icComps) {
+        JAXBElement subel = toComponent((CalendarComponent)o,
+                                        pattern);
+        aetcc.getValarm().add((ValarmType)subel.getValue());
+      }
+    }
+
+    return el;
+  }
+
+  /**
+   * @param icprops
+   * @param comp
+   * @param pattern
+   * @throws Throwable
+   */
+  public static void processProperties(final PropertyList icprops,
+                                       final BaseComponentType comp,
+                                       final BaseComponentType pattern) throws Throwable {
+    if ((icprops == null) || icprops.isEmpty()) {
+      return;
+    }
+
+    comp.setProperties(new ArrayOfProperties());
+    List<JAXBElement<? extends BasePropertyType>> pl = comp.getProperties().getBasePropertyOrTzid();
+
+    Iterator it = icprops.iterator();
+
+    while (it.hasNext()) {
+      Property prop = (Property)it.next();
+
+      PropertyInfoIndex pii = PropertyInfoIndex.lookupPname(prop.getName());
+
+      if (pii == null) {
+        continue;
+      }
+
+      if (!emit(pattern, comp.getClass(), pii.getXmlClass())) {
+        continue;
+      }
+
+      JAXBElement<? extends BasePropertyType> xmlprop =
+          doProperty(prop, pii);
+
+      if (xmlprop != null) {
+        pl.add(xmlprop);
+      }
+    }
+  }
+
+  static JAXBElement<? extends BasePropertyType> doProperty(final Property prop,
+                                                     final PropertyInfoIndex pii) throws Throwable {
+    switch (pii) {
+      case ACTION:
+        /* ------------------- Action: Alarm -------------------- */
+
+        ActionPropType a = new ActionPropType();
+        a.setText(prop.getValue());
+        return of.createAction(a);
+
+      case ATTACH:
+        /* ------------------- Attachments -------------------- */
+        //          pl.add(setAttachment(att));
+        return null;
+
+      case ATTENDEE:
+        /* ------------------- Attendees -------------------- */
+
+        return of.createAttendee(makeAttendee((Attendee)prop));
+
+      case BUSYTYPE:
+        return null;
+
+      case CATEGORIES:
+        /* ------------------- Categories -------------------- */
+
+        // LANG - filter on language - group language in one cat list?
+
+        CategoriesPropType c = new CategoriesPropType();
+        CategoryList cats = ((Categories)prop).getCategories();
+
+        Iterator pit = cats.iterator();
+        while (pit.hasNext()) {
+          c.getText().add((String)pit.next());
+        }
+
+        return of.createCategories((CategoriesPropType)langProp(c,
+                                                                prop));
+
+      case CLASS:
+        /* ------------------- Class -------------------- */
+
+        ClassPropType cl = new ClassPropType();
+        cl.setText(prop.getValue());
+        return of.createClass(cl);
+
+      case COMMENT:
+        /* ------------------- Comments -------------------- */
+
+        CommentPropType cm = new CommentPropType();
+        cm.setText(prop.getValue());
+        return of.createComment((CommentPropType)langProp(cm, prop));
+
+      case COMPLETED:
+        /* ------------------- Completed -------------------- */
+
+        CompletedPropType cmp = new CompletedPropType();
+        cmp.setUtcDateTime(XcalUtil.getXMlUTCCal(prop.getValue()));
+        return of.createCompleted(cmp);
+
+      case CONTACT:
+        /* ------------------- Contact -------------------- */
+
+        // LANG
+        ContactPropType ct = new ContactPropType();
+        ct.setText(prop.getValue());
+
+        return of.createContact(
+                                (ContactPropType)langProp(ct, prop));
+
+      case CREATED:
+        /* ------------------- Created -------------------- */
+
+        CreatedPropType created = new CreatedPropType();
+        created.setUtcDateTime(XcalUtil.getXMlUTCCal(prop.getValue()));
+        return of.createCreated(created);
+
+      case DESCRIPTION:
+        /* ------------------- Description -------------------- */
+
+        DescriptionPropType desc = new DescriptionPropType();
+        desc.setText(prop.getValue());
+        return of.createDescription((DescriptionPropType)langProp(desc, prop));
+
+      case DTEND:
+        /* ------------------- DtEnd -------------------- */
+
+        DtendPropType dtend = (DtendPropType)makeDateDatetime(new DtendPropType(),
+                                                              prop);
+        return of.createDtend(dtend);
+
+      case DTSTAMP:
+        /* ------------------- DtStamp -------------------- */
+
+        DtstampPropType dtstamp = new DtstampPropType();
+        dtstamp.setUtcDateTime(XcalUtil.getXMlUTCCal(prop.getValue()));
+        return of.createDtstamp(dtstamp);
+
+      case DTSTART:
+        /* ------------------- DtStart -------------------- */
+
+        DtstartPropType dtstart = (DtstartPropType)makeDateDatetime(new DtstartPropType(),
+                                                                    prop);
+        return of.createDtstart(dtstart);
+
+      case DUE:
+        /* ------------------- Due -------------------- */
+
+        DuePropType due = (DuePropType)makeDateDatetime(new DuePropType(),
+                                                        prop);
+        return of.createDue(due);
+
+      case DURATION:
+        /* ------------------- Duration -------------------- */
+
+        DurationPropType dur = new DurationPropType();
+
+        dur.setDuration(prop.getValue());
+        return of.createDuration(dur);
+
+      case EXDATE:
+        /* ------------------- ExDate --below------------ */
+        return null;
+
+      case EXRULE:
+        /* ------------------- ExRule --below------------- */
+
+        ExrulePropType er = new ExrulePropType();
+        er.setRecur(doRecur(((RRule)prop).getRecur()));
+
+        return of.createExrule(er);
+
+      case FREEBUSY:
+        /* ------------------- freebusy -------------------- */
+
+        FreeBusy icfb = (FreeBusy)prop;
+        PeriodList fbps = icfb.getPeriods();
+
+        if (Util.isEmpty(fbps)) {
+          return null;
+        }
+
+        FreebusyPropType fb = new FreebusyPropType();
+
+        String fbtype = paramVal(prop, Parameter.FBTYPE);
+
+        if (fbtype != null) {
+          ArrayOfParameters pars = getAop(fb);
+
+          FbtypeParamType f = new FbtypeParamType();
+
+          f.setText(fbtype);
+          JAXBElement<FbtypeParamType> param = of.createFbtype(f);
+          pars.getBaseParameter().add(param);
+        }
+
+        List<PeriodType> pdl =  fb.getPeriod();
+
+        for (Object o: fbps) {
+          Period p = (Period)o;
+          PeriodType np = new PeriodType();
+
+          np.setStart(XcalUtil.getXMlUTCCal(p.getStart().toString()));
+          np.setEnd(XcalUtil.getXMlUTCCal(p.getEnd().toString()));
+          pdl.add(np);
+        }
+
+        return of.createFreebusy(fb);
+
+      case GEO:
+        /* ------------------- Geo -------------------- */
+
+        Geo geo = (Geo)prop;
+        GeoPropType g = new GeoPropType();
+
+        g.setLatitude(geo.getLatitude().floatValue());
+        g.setLatitude(geo.getLongitude().floatValue());
+        return of.createGeo(g);
+
+      case LAST_MODIFIED:
+        /* ------------------- LastModified -------------------- */
+
+        LastModifiedPropType lm = new LastModifiedPropType();
+        lm.setUtcDateTime(XcalUtil.getXMlUTCCal(prop.getValue()));
+        return of.createLastModified(lm);
+
+      case LOCATION:
+        /* ------------------- Location -------------------- */
+
+        LocationPropType l = new LocationPropType();
+        l .setText(prop.getValue());
+
+        return of.createLocation((LocationPropType)langProp(l, prop));
+
+      case METHOD:
+        /* ------------------- Method -------------------- */
+
+        MethodPropType m = new MethodPropType();
+
+        m.setText(prop.getValue());
+        return of.createMethod(m);
+
+      case ORGANIZER:
+        /* ------------------- Organizer -------------------- */
+
+        return of.createOrganizer(makeOrganizer((Organizer)prop));
+
+      case PERCENT_COMPLETE:
+        /* ------------------- PercentComplete -------------------- */
+
+        PercentCompletePropType p = new PercentCompletePropType();
+        p.setInteger(BigInteger.valueOf(((PercentComplete)prop).getPercentage()));
+
+        return of.createPercentComplete(p);
+
+      case PRIORITY:
+        /* ------------------- Priority -------------------- */
+
+        PriorityPropType pr = new PriorityPropType();
+        pr.setInteger(BigInteger.valueOf(((Priority)prop).getLevel()));
+
+        return of.createPriority(pr);
+
+      case PRODID:
+        /* ------------------- Prodid -------------------- */
+        ProdidPropType prod = new ProdidPropType();
+        prod.setText(prop.getValue());
+        return of.createProdid(prod);
+
+      case RDATE:
+        /* ------------------- RDate ------------------- */
+        // XXX Todo
+        return null;
+
+      case RECURRENCE_ID:
+        /* ------------------- RecurrenceID -------------------- */
+
+        RecurrenceIdPropType ri = new RecurrenceIdPropType();
+        String strval = prop.getValue();
+
+        if (dateOnly(prop)) {
+          // RECUR - fix all day recurrences sometime
+          if (strval.length() > 8) {
+            // Try to fix up bad all day recurrence ids. - assume a local timezone
+            strval = strval.substring(0, 8);
+          }
+
+          ri.setDate(XcalUtil.fromDtval(strval));
+        } else {
+          XcalUtil.initDt(ri, strval, getTzid(prop));
+        }
+
+        return of.createRecurrenceId(ri);
+
+      case RELATED_TO:
+        /* ------------------- RelatedTo -------------------- */
+
+        RelatedToPropType rt = new RelatedToPropType();
+
+        String relType = paramVal(prop, Parameter.RELTYPE);
+        String value = paramVal(prop, Parameter.VALUE);
+
+        if ((value == null) || "uid".equalsIgnoreCase(value)) {
+          rt.setUid(prop.getValue());
+        } else if ("uri".equalsIgnoreCase(value)) {
+          rt.setUri(prop.getValue());
+        } else {
+          rt.setText(prop.getValue());
+        }
+
+        if (relType != null) {
+          ArrayOfParameters pars = getAop(rt);
+
+          ReltypeParamType r = new ReltypeParamType();
+          r.setText(relType);
+          JAXBElement<ReltypeParamType> param = of.createReltype(r);
+          pars.getBaseParameter().add(param);
+        }
+
+        return of.createRelatedTo(rt);
+
+      case REPEAT:
+        /* ------------------- Repeat Alarm -------------------- */
+        Repeat rept = (Repeat)prop;
+        RepeatPropType rep = new RepeatPropType();
+        rep.setInteger(BigInteger.valueOf(rept.getCount()));
+
+        return of.createRepeat(rep);
+
+      case REQUEST_STATUS:
+        /* ------------------- RequestStatus -------------------- */
+
+        // XXX Later
+        return null;
+
+      case RESOURCES:
+        /* ------------------- Resources -------------------- */
+
+        ResourcesPropType r = new ResourcesPropType();
+
+        List<String> rl = r.getText();
+        ResourceList rlist = ((Resources)prop).getResources();
+
+        Iterator rlit = rlist.iterator();
+        while (rlit.hasNext()) {
+          rl.add((String)rlit.next());
+        }
+
+        return of.createResources(r);
+
+      case RRULE:
+        /* ------------------- RRule ------------------- */
+
+        RrulePropType rrp = new RrulePropType();
+        rrp.setRecur(doRecur(((RRule)prop).getRecur()));
+
+        return of.createRrule(rrp);
+
+      case SEQUENCE:
+        /* ------------------- Sequence -------------------- */
+
+        SequencePropType s = new SequencePropType();
+        s.setInteger(BigInteger.valueOf(((Sequence)prop).getSequenceNo()));
+
+        return of.createSequence(s);
+
+      case STATUS:
+        /* ------------------- Status -------------------- */
+
+        StatusPropType st = new StatusPropType();
+
+        st.setText(prop.getValue());
+        return of.createStatus(st);
+
+      case SUMMARY:
+        /* ------------------- Summary -------------------- */
+
+        SummaryPropType sum = new SummaryPropType();
+        sum.setText(prop.getValue());
+
+        sum = (SummaryPropType)langProp(sum, prop);
+
+        return of.createSummary(sum);
+
+      case TRIGGER:
+        /* ------------------- Trigger - alarm -------------------- */
+        TriggerPropType trig = new TriggerPropType();
+
+        String valType = paramVal(prop, Parameter.VALUE);
+
+        if ((valType == null) ||
+            (valType.equalsIgnoreCase(Value.DURATION.getValue()))) {
+          trig.setDuration(prop.getValue());
+          String rel = paramVal(prop, Parameter.RELATED);
+          if (rel != null) {
+            ArrayOfParameters pars = getAop(trig);
+
+            RelatedParamType rpar = new RelatedParamType();
+            rpar.setText(IcalDefs.alarmTriggerRelatedEnd);
+            JAXBElement<RelatedParamType> param = of.createRelated(rpar);
+            pars.getBaseParameter().add(param);
+          }
+        } else if (valType.equalsIgnoreCase(Value.DATE_TIME.getValue())) {
+          //t.setDateTime(val.getTrigger());
+          trig.setDateTime(XcalUtil.getXMlUTCCal(prop.getValue()));
+        }
+
+        return of.createTrigger(trig);
+
+      case TRANSP:
+        /* ------------------- Transp -------------------- */
+
+        TranspPropType t = new TranspPropType();
+        t.setText(prop.getValue());
+        return of.createTransp(t);
+
+      case TZID:
+      case TZNAME:
+      case TZOFFSETFROM:
+      case TZOFFSETTO:
+      case TZURL:
+        return null;
+
+      case UID:
+        /* ------------------- Uid -------------------- */
+
+        UidPropType uid = new UidPropType();
+        uid.setText(prop.getValue());
+        return of.createUid(uid);
+
+      case URL:
+        /* ------------------- Url -------------------- */
+
+        UrlPropType u = new UrlPropType();
+
+        u.setUri(prop.getValue());
+        return of.createUrl(u);
+
+      case VERSION:
+        /* ------------------- Version - vcal only -------------------- */
+
+        VersionPropType vers = new VersionPropType();
+        vers.setText(prop.getValue());
+        return of.createVersion(vers);
+
+      case XBEDEWORK_COST:
+        /* ------------------- Cost -------------------- */
+
+        XBedeworkCostPropType cst = new XBedeworkCostPropType();
+
+        cst.setText(prop.getValue());
+        return of.createXBedeworkCost(cst);
+
+      default:
+        if (prop instanceof XProperty) {
+          /* ------------------------- x-property --------------------------- */
+
+          String name = prop.getName();
+
+          PropertyInfoIndex xpii = PropertyInfoIndex.lookupPname(prop.getName());
+
+          if (pii == null) {
+            return null;
+          }
+
+          return null;
+        }
+
+    } // switch (pii)
+
+    return null;
+  }
+
+  /** Build recurring properties from ical recurrence.
+   *
+   * @param r
+   * @return RecurTyp filled in
+   * @throws Throwable
+   */
+  public static RecurType doRecur(final Recur r) throws Throwable {
+    RecurType rt = new RecurType();
+
+    rt.setFreq(FreqRecurType.fromValue(r.getFrequency()));
+    if (r.getCount() > 0) {
+      rt.setCount(BigInteger.valueOf(r.getCount()));
+    }
+
+    Date until = r.getUntil();
+    if (until != null) {
+      UntilRecurType u = new UntilRecurType();
+      XcalUtil.initUntilRecur(u, until.toString());
+    }
+
+    if (r.getInterval() > 0) {
+      rt.setInterval(String.valueOf(r.getInterval()));
+    }
+
+    listFromNumberList(rt.getBysecond(),
+                       r.getSecondList());
+
+    listFromNumberList(rt.getByminute(),
+                       r.getMinuteList());
+
+    listFromNumberList(rt.getByhour(),
+                       r.getHourList());
+
+    if (r.getDayList() != null) {
+      List<String> l = rt.getByday();
+
+      for (Object o: r.getDayList()) {
+        l.add(((WeekDay)o).getDay());
+      }
+    }
+
+    listFromNumberList(rt.getByyearday(),
+                       r.getYearDayList());
+
+    intlistFromNumberList(rt.getBymonthday(),
+                          r.getMonthDayList());
+
+    listFromNumberList(rt.getByweekno(),
+                       r.getWeekNoList());
+
+    intlistFromNumberList(rt.getBymonth(),
+                          r.getMonthList());
+
+    bigintlistFromNumberList(rt.getBysetpos(),
+                             r.getSetPosList());
+
+    return rt;
+  }
+
+  private static void listFromNumberList(final List<String> l,
+                                        final NumberList nl) {
+    if (nl == null) {
+      return;
+    }
+
+    for (Object o: nl) {
+      l.add((String)o);
+    }
+  }
+
+  private static void intlistFromNumberList(final List<Integer> l,
+                                            final NumberList nl) {
+    if (nl == null) {
+      return;
+    }
+
+    for (Object o: nl) {
+      l.add(Integer.valueOf((String)o));
+    }
+  }
+
+  private static void bigintlistFromNumberList(final List<BigInteger> l,
+                                            final NumberList nl) {
+    if (nl == null) {
+      return;
+    }
+
+    for (Object o: nl) {
+      l.add(BigInteger.valueOf(Integer.valueOf((String)o)));
+    }
+  }
+
+  private static String getTzid(final Property p) {
+    TzId tzidParam = (TzId)p.getParameter(Parameter.TZID);
+
+    if (tzidParam == null) {
+      return null;
+    }
+
+    return tzidParam.getValue();
+  }
+
+  private static boolean dateOnly(final Property p) {
+    Value valParam = (Value)p.getParameter(Parameter.VALUE);
+
+    if ((valParam == null) || (valParam.getValue() == null)) {
+      return false;
+    }
+
+    return valParam.getValue().toUpperCase().equals(Value.DATE);
+  }
+
+  private static String paramVal(final Property p,
+                                 final String paramName) {
+    Parameter param = p.getParameter(paramName);
+
+    if ((param == null) || (param.getValue() == null)) {
+      return null;
+    }
+
+    return param.getValue();
+  }
+
+  private static BasePropertyType langProp(final BasePropertyType prop,
+                                           final Property p) {
+    Language langParam = (Language)p.getParameter(Parameter.LANGUAGE);
+
+    if (langParam == null) {
+      return prop;
+    }
+
+    String lang = langParam.getValue();
+
+    if (lang == null) {
+      return prop;
+    }
+
+    ArrayOfParameters pars = getAop(prop);
+
+    LanguageParamType l = new LanguageParamType();
+    l.setText(lang);
+
+    JAXBElement<LanguageParamType> param = of.createLanguage(l);
+    pars.getBaseParameter().add(param);
+
+    return prop;
+  }
+
+  private static BasePropertyType tzidProp(final BasePropertyType prop,
+                                           final String val) {
+    if (val == null) {
+      return prop;
+    }
+
+    ArrayOfParameters pars = getAop(prop);
+
+    TzidParamType tzid = new TzidParamType();
+    tzid.setText(val);
+    JAXBElement<TzidParamType> t = of.createTzid(tzid);
+    pars.getBaseParameter().add(t);
+
+    return prop;
+  }
+
+  private static BasePropertyType altrepProp(final BasePropertyType prop,
+                                             final String val) {
+    if (val == null) {
+      return prop;
+    }
+
+    ArrayOfParameters pars = getAop(prop);
+
+    AltrepParamType a = new AltrepParamType();
+    a.setUri(val);
+    JAXBElement<AltrepParamType> param = of.createAltrep(a);
+    pars.getBaseParameter().add(param);
+
+    return prop;
+  }
+
+  private static ArrayOfParameters getAop(final BasePropertyType prop) {
+    ArrayOfParameters pars = prop.getParameters();
+
+    if (pars == null) {
+      pars = new ArrayOfParameters();
+      prop.setParameters(pars);
+    }
+
+    return pars;
+  }
+
+  private static DateDatetimePropertyType makeDateDatetime(final DateDatetimePropertyType p,
+                                                           final Property prop) throws Throwable {
+    XcalUtil.initDt(p, prop.getValue(), getTzid(prop));
+
+    return p;
+  }
+
+  private static boolean emit(final BaseComponentType pattern,
+                              final Class compCl,
+                              final Class... cl) {
+    if (pattern == null) {
+      return true;
+    }
+
+    if (!compCl.getName().equals(pattern.getClass().getName())) {
+      return false;
+    }
+
+    if ((cl == null) | (cl.length == 0)) {
+      // Any property
+      return true;
+    }
+
+    String className = cl[0].getName();
+
+    if (BasePropertyType.class.isAssignableFrom(cl[0])) {
+      if (pattern.getProperties() == null) {
+        return false;
+      }
+
+      List<JAXBElement<? extends BasePropertyType>> patternProps =
+         pattern.getProperties().getBasePropertyOrTzid();
+
+      for (JAXBElement<? extends BasePropertyType> jp: patternProps) {
+        if (jp.getValue().getClass().getName().equals(className)) {
+          return true;
+        }
+      }
+
+      return false;
+    }
+
+    List<JAXBElement<? extends BaseComponentType>> patternComps =
+      XcalUtil.getComponents(pattern);
+
+    if (patternComps == null) {
+      return false;
+    }
+
+    // Check for component
+
+    for (JAXBElement<? extends BaseComponentType> jp: patternComps) {
+      if (jp.getValue().getClass().getName().equals(className)) {
+        return emit(pattern, cl[0], Arrays.copyOfRange(cl, 1, cl.length - 1));
+      }
+    }
+
+    return false;
+  }
+
+  /** make an attendee
+   *
+   * @param val
+   * @return Attendee
+   * @throws Throwable
+   */
+  public static AttendeePropType makeAttendee(final Attendee val) throws Throwable {
+    AttendeePropType prop = new AttendeePropType();
+
+    prop.setCalAddress(val.getValue());
+
+    ArrayOfParameters pars = new ArrayOfParameters();
+    JAXBElement<? extends BaseParameterType> param;
+    prop.setParameters(pars);
+
+    Rsvp rsvp = (Rsvp)val.getParameter(Parameter.RSVP);
+    if (rsvp.getRsvp()) {
+      RsvpParamType r = new RsvpParamType();
+      r.setBoolean(true);
+      param = of.createRsvp(r);
+      pars.getBaseParameter().add(param);
+    }
+
+    String temp = paramVal(val, Parameter.CN);
+    if (temp != null) {
+      CnParamType cn = new CnParamType();
+      cn.setText(temp);
+      param = of.createCn(cn);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.PARTSTAT);
+    if (temp == null) {
+      temp = IcalDefs.partstatValNeedsAction;
+    }
+
+    PartstatParamType partstat = new PartstatParamType();
+    partstat.setText(temp);
+    param = of.createPartstat(partstat);
+    pars.getBaseParameter().add(param);
+
+    temp = paramVal(val, Parameter.SCHEDULE_STATUS);
+    if (temp != null) {
+      ScheduleStatusParamType ss = new ScheduleStatusParamType();
+      ss.setText(temp);
+      param = of.createScheduleStatus(ss);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.CUTYPE);
+    if (temp != null) {
+      CutypeParamType c = new CutypeParamType();
+      c.setText(temp);
+      param = of.createCutype(c);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.DELEGATED_FROM);
+    if (temp != null) {
+      DelegatedFromParamType df = new DelegatedFromParamType();
+      df.getCalAddress().add(temp);
+      param = of.createDelegatedFrom(df);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.DELEGATED_TO);
+    if (temp != null) {
+      DelegatedToParamType dt = new DelegatedToParamType();
+      dt.getCalAddress().add(temp);
+      param = of.createDelegatedTo(dt);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.DIR);
+    if (temp != null) {
+      DirParamType d = new DirParamType();
+      d.setUri(temp);
+      param = of.createDir(d);
+      pars.getBaseParameter().add(param);
+    }
+
+    prop = (AttendeePropType)langProp(prop, val);
+
+    temp = paramVal(val, Parameter.MEMBER);
+    if (temp != null) {
+      MemberParamType m = new MemberParamType();
+      m.getCalAddress().add(temp);
+      param = of.createMember(m);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.ROLE);
+    if (temp != null) {
+      RoleParamType r = new RoleParamType();
+      r.setText(temp);
+      param = of.createRole(r);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.SENT_BY);
+    if (temp != null) {
+      SentByParamType sb = new SentByParamType();
+      sb.setCalAddress(temp);
+      param = of.createSentBy(sb);
+      pars.getBaseParameter().add(param);
+    }
+
+    return prop;
+  }
+
+  /**
+   * @param val
+   * @return Organizer
+   * @throws Throwable
+   */
+  public static OrganizerPropType makeOrganizer(final Organizer val) throws Throwable {
+    OrganizerPropType prop = new OrganizerPropType();
+
+    prop.setCalAddress(val.getValue());
+
+    ArrayOfParameters pars = new ArrayOfParameters();
+    JAXBElement<? extends BaseParameterType> param;
+    prop.setParameters(pars);
+
+    String temp = paramVal(val, Parameter.SCHEDULE_STATUS);
+    if (temp != null) {
+      ScheduleStatusParamType ss = new ScheduleStatusParamType();
+      ss.setText(temp);
+      param = of.createScheduleStatus(ss);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.CN);
+    if (temp != null) {
+      CnParamType cn = new CnParamType();
+      cn.setText(temp);
+      param = of.createCn(cn);
+      pars.getBaseParameter().add(param);
+    }
+
+    temp = paramVal(val, Parameter.DIR);
+    if (temp != null) {
+      DirParamType d = new DirParamType();
+      d.setUri(temp);
+      param = of.createDir(d);
+      pars.getBaseParameter().add(param);
+    }
+
+    prop = (OrganizerPropType)langProp(prop, val);
+
+    temp = paramVal(val, Parameter.SENT_BY);
+    if (temp != null) {
+      SentByParamType sb = new SentByParamType();
+      sb.setCalAddress(temp);
+      param = of.createSentBy(sb);
+      pars.getBaseParameter().add(param);
+    }
+
+    return prop;
+  }
+
+}

Modified: trunk/src/edu/rpi/cmt/calendar/PropertyIndex.java
===================================================================
--- trunk/src/edu/rpi/cmt/calendar/PropertyIndex.java	2011-08-11 19:57:28 UTC (rev 255)
+++ trunk/src/edu/rpi/cmt/calendar/PropertyIndex.java	2011-08-23 19:42:24 UTC (rev 256)
@@ -21,8 +21,68 @@
 import edu.rpi.sss.util.xml.tagdefs.BedeworkServerTags;
 import edu.rpi.sss.util.xml.tagdefs.XcalTags;
 
+import ietf.params.xml.ns.icalendar_2.ActionPropType;
+import ietf.params.xml.ns.icalendar_2.AlarmComponentType;
+import ietf.params.xml.ns.icalendar_2.AttachPropType;
+import ietf.params.xml.ns.icalendar_2.AttendeePropType;
+import ietf.params.xml.ns.icalendar_2.BusytypePropType;
+import ietf.params.xml.ns.icalendar_2.CalscalePropType;
+import ietf.params.xml.ns.icalendar_2.CategoriesPropType;
+import ietf.params.xml.ns.icalendar_2.ClassPropType;
+import ietf.params.xml.ns.icalendar_2.CommentPropType;
+import ietf.params.xml.ns.icalendar_2.CompletedPropType;
+import ietf.params.xml.ns.icalendar_2.ContactPropType;
+import ietf.params.xml.ns.icalendar_2.CreatedPropType;
+import ietf.params.xml.ns.icalendar_2.DescriptionPropType;
+import ietf.params.xml.ns.icalendar_2.DtendPropType;
+import ietf.params.xml.ns.icalendar_2.DtstampPropType;
+import ietf.params.xml.ns.icalendar_2.DtstartPropType;
+import ietf.params.xml.ns.icalendar_2.DuePropType;
+import ietf.params.xml.ns.icalendar_2.DurationPropType;
+import ietf.params.xml.ns.icalendar_2.ExdatePropType;
+import ietf.params.xml.ns.icalendar_2.ExrulePropType;
+import ietf.params.xml.ns.icalendar_2.FreebusyPropType;
+import ietf.params.xml.ns.icalendar_2.GeoPropType;
+import ietf.params.xml.ns.icalendar_2.LanguageParamType;
+import ietf.params.xml.ns.icalendar_2.LastModifiedPropType;
+import ietf.params.xml.ns.icalendar_2.LocationPropType;
+import ietf.params.xml.ns.icalendar_2.MethodPropType;
+import ietf.params.xml.ns.icalendar_2.OrganizerPropType;
+import ietf.params.xml.ns.icalendar_2.PercentCompletePropType;
+import ietf.params.xml.ns.icalendar_2.PriorityPropType;
+import ietf.params.xml.ns.icalendar_2.ProdidPropType;
+import ietf.params.xml.ns.icalendar_2.RdatePropType;
+import ietf.params.xml.ns.icalendar_2.RecurrenceIdPropType;
+import ietf.params.xml.ns.icalendar_2.RelatedToPropType;
+import ietf.params.xml.ns.icalendar_2.RepeatPropType;
+import ietf.params.xml.ns.icalendar_2.RequestStatusPropType;
+import ietf.params.xml.ns.icalendar_2.ResourcesPropType;
+import ietf.params.xml.ns.icalendar_2.RrulePropType;
+import ietf.params.xml.ns.icalendar_2.SequencePropType;
+import ietf.params.xml.ns.icalendar_2.StatusPropType;
+import ietf.params.xml.ns.icalendar_2.SummaryPropType;
+import ietf.params.xml.ns.icalendar_2.TranspPropType;
+import ietf.params.xml.ns.icalendar_2.TriggerPropType;
+import ietf.params.xml.ns.icalendar_2.TzidParamType;
+import ietf.params.xml.ns.icalendar_2.TzidPropType;
+import ietf.params.xml.ns.icalendar_2.TznamePropType;
+import ietf.params.xml.ns.icalendar_2.TzoffsetfromPropType;
+import ietf.params.xml.ns.icalendar_2.TzoffsettoPropType;
+import ietf.params.xml.ns.icalendar_2.TzurlPropType;
+import ietf.params.xml.ns.icalendar_2.UidPropType;
+import ietf.params.xml.ns.icalendar_2.UrlPropType;
+import ietf.params.xml.ns.icalendar_2.ValarmType;
+import ietf.params.xml.ns.icalendar_2.VersionPropType;
+import ietf.params.xml.ns.icalendar_2.VeventType;
+import ietf.params.xml.ns.icalendar_2.VfreebusyType;
+import ietf.params.xml.ns.icalendar_2.VjournalType;
+import ietf.params.xml.ns.icalendar_2.VtimezoneType;
+import ietf.params.xml.ns.icalendar_2.VtodoType;
+import ietf.params.xml.ns.icalendar_2.XBedeworkCostPropType;
+
 import java.io.Serializable;
 import java.util.HashMap;
+import java.util.Map;
 
 import javax.xml.namespace.QName;
 
@@ -34,6 +94,8 @@
   private PropertyIndex() {};
 
   static class ComponentFlags {
+    private boolean vcalendarProperty;
+
     private boolean eventProperty;
     private boolean todoProperty;
     private boolean journalProperty;
@@ -60,6 +122,10 @@
       this.vavailabilityProperty = vavailabilityProperty;
       this.availableProperty = availableProperty;
     }
+
+    ComponentFlags(final boolean vcalendarProperty) {
+      this.vcalendarProperty = vcalendarProperty;
+    }
   }
 
   static final ComponentFlags noComponent =
@@ -119,6 +185,9 @@
   static final ComponentFlags allComponents =
      new ComponentFlags(true, true, true, true, true, true, false, false);
 
+  static final ComponentFlags vcalendarOnly =
+     new ComponentFlags(true);
+
   private static boolean IS_MULTI = true;
 
   private static boolean IS_SINGLE = false;
@@ -132,6 +201,119 @@
   private static boolean NOT_IMMUTABLE = false;
 
   /** */
+  public static enum ComponentInfoIndex {
+    /** */
+    UNKNOWN_COMPONENT(null, null, null),
+
+    /** */
+    VALARM(XcalTags.valarm, "VALARM", ValarmType.class),
+
+    /** */
+    VEVENT(XcalTags.vevent, "VEVENT", VeventType.class),
+
+    /** */
+    VFREEBUSY(XcalTags.vfreebusy, "VFREEBUSY", VfreebusyType.class),
+
+    /** */
+    VJOURNAL(XcalTags.vjournal, "VJOURNAL", VjournalType.class),
+
+    /** */
+    VTIMEZONE(XcalTags.vtimezone, "VTIMEZONE", VtimezoneType.class),
+
+    /** */
+    VTODO(XcalTags.vtodo, "VTODO", VtodoType.class),
+           ;
+
+    private QName qname;
+
+    private String pname;
+
+    private Class xmlClass;
+
+    private static Map<String, ComponentInfoIndex> pnameLookup =
+      new HashMap<String, ComponentInfoIndex>();
+
+    private static Map<QName, ComponentInfoIndex> qnameLookup =
+      new HashMap<QName, ComponentInfoIndex>();
+
+    private static Map<Class, ComponentInfoIndex> xmlClassLookup =
+        new HashMap<Class, ComponentInfoIndex>();
+
+    static {
+      for (ComponentInfoIndex cii: values()) {
+        String pname = cii.getPname();
+
+        if (pname != null) {
+          pname = pname.toLowerCase();
+        }
+        pnameLookup.put(pname, cii);
+
+        qnameLookup.put(cii.getQname(), cii);
+
+        xmlClassLookup.put(cii.xmlClass, cii);
+      }
+    }
+
+    ComponentInfoIndex(final QName qname,
+                      final String pname,
+                      final Class xmlClass) {
+      this.qname = qname;
+      this.pname = pname;
+      this.xmlClass = xmlClass;
+    }
+
+    /** get the qname
+     *
+     * @return qname
+     */
+    public QName getQname() {
+      return qname;
+    }
+
+    /** get the property name
+     *
+     * @return property name
+     */
+    public String getPname() {
+      return pname;
+    }
+
+    /** get the XML class
+     *
+     * @return class
+     */
+    public Class getXmlClass() {
+      return xmlClass;
+    }
+
+    /** get the index given the XML class
+     * @param cl
+     * @return ComponentInfoIndex
+     */
+    public static ComponentInfoIndex fromXmlClass(final Class cl) {
+      return xmlClassLookup.get(cl);
+    }
+
+    /** get the index given the property name
+     *
+     * @param val
+     * @return ComponentInfoIndex
+     */
+    public static ComponentInfoIndex lookupPname(final String val) {
+      return pnameLookup.get(val.toLowerCase());
+    }
+
+    /** get the index given the qname
+     *
+     * @param val
+     * @return ComponentInfoIndex
+     */
+    public static ComponentInfoIndex lookupQname(final QName val) {
+      return qnameLookup.get(val);
+    }
+  }
+
+  /** */
   public static enum DataType {
     /** */
     BINARY(XcalTags.binaryVal),
@@ -377,281 +559,314 @@
   /** */
   public static enum PropertyInfoIndex {
     /** */
-    UNKNOWN_PROPERTY(null, null,
+    UNKNOWN_PROPERTY(null, null, null,
                      IS_SINGLE, noComponent),
 
     /** Alarm only: action */
-    ACTION(XcalTags.action, "ACTION",
+    ACTION(XcalTags.action, "ACTION", ActionPropType.class,
            IS_SINGLE, alarmOnly),
 
     /** Multi-valued attachment */
-    ATTACH(XcalTags.attach, "ATTACH",
+    ATTACH(XcalTags.attach, "ATTACH", AttachPropType.class,
            DataType.SPECIAL,
            IS_MULTI, event_Todo_Journal_Alarm),
 
     /** attendee */
-    ATTENDEE(XcalTags.attendee, "ATTENDEE",
+    ATTENDEE(XcalTags.attendee, "ATTENDEE", AttendeePropType.class,
              DataType.CUA,
              IS_MULTI, notTimezone),
 
     /** */
-    BUSYTYPE(XcalTags.busytype, "BUSYTYPE",
+    BUSYTYPE(XcalTags.busytype, "BUSYTYPE", BusytypePropType.class,
              IS_SINGLE, vavailabilityOnly),
 
     /** String names */
-    CATEGORIES(XcalTags.categories, "CATEGORIES",
+    CATEGORIES(XcalTags.categories, "CATEGORIES", CategoriesPropType.class,
                IS_MULTI, event_Todo_Journal_Alarm),
 
     /** classification */
-    CLASS(XcalTags._class, "CLASS",
+    CLASS(XcalTags._class, "CLASS", ClassPropType.class,
           IS_SINGLE, event_Todo_Journal),
 
     /** String comment */
-    COMMENT(XcalTags.comment, "COMMENT",
+    COMMENT(XcalTags.comment, "COMMENT", CommentPropType.class,
             IS_MULTI, notAlarm),
 
     /** date/date-time completed */
-    COMPLETED(XcalTags.completed, "COMPLETED",
+    COMPLETED(XcalTags.completed, "COMPLETED", CompletedPropType.class,
               DataType.DATE_TIME,
               IS_SINGLE, todoOnly),
 
     /** String contact */
-    CONTACT(XcalTags.contact, "CONTACT",
+    CONTACT(XcalTags.contact, "CONTACT", ContactPropType.class,
             IS_MULTI, event_Todo_Journal_Freebusy),
 
     /** UTC datetime */
-    CREATED(XcalTags.created, "CREATED",
+    CREATED(XcalTags.created, "CREATED", CreatedPropType.class,
             DataType.DATE_TIME,
             IS_SINGLE, event_Todo_Journal_Freebusy),
 
     /** long description */
-    DESCRIPTION(XcalTags.description, "DESCRIPTION",
+    DESCRIPTION(XcalTags.description, "DESCRIPTION", DescriptionPropType.class,
                 IS_SINGLE, IS_MULTI, event_Todo_Journal_Alarm),
 
     /** Event only: end date */
-    DTEND(XcalTags.dtend, "DTEND",
+    DTEND(XcalTags.dtend, "DTEND", DtendPropType.class,
           DataType.DATE_TIME,
           IS_SINGLE, event_Freebusy),
 
     /** date stamp */
-    DTSTAMP(XcalTags.dtstamp, "DTSTAMP",
+    DTSTAMP(XcalTags.dtstamp, "DTSTAMP", DtstampPropType.class,
             DataType.DATE_TIME,
             IS_SINGLE, event_Todo_Journal_Freebusy,
             NOT_PARAM, NOT_IMMUTABLE),
 
     /** start date/time */
-    DTSTART(XcalTags.dtstart, "DTSTART",
+    DTSTART(XcalTags.dtstart, "DTSTART", DtstartPropType.class,
             DataType.DATE_TIME,
             IS_SINGLE, notAlarm),
 
     /** tod-: due time */
-    DUE(XcalTags.due, "DUE",
+    DUE(XcalTags.due, "DUE", DuePropType.class,
         DataType.DATE_TIME,
         IS_SINGLE, todoOnly),
 
     /** Duration of event/task etc */
-    DURATION(XcalTags.duration, "DURATION",
+    DURATION(XcalTags.duration, "DURATION", DurationPropType.class,
              DataType.DURATION,
              IS_SINGLE, event_Todo_Freebusy_Alarm),
 
     /** Exception date */
-    EXDATE(XcalTags.exdate, "EXDATE",
+    EXDATE(XcalTags.exdate, "EXDATE", ExdatePropType.class,
            DataType.DATE_TIME,
            IS_MULTI, event_Todo_Journal_Timezone),
 
     /** Exception rule */
-    EXRULE(XcalTags.exrule, "EXRULE",
+    EXRULE(XcalTags.exrule, "EXRULE", ExrulePropType.class,
            DataType.RECUR,
            IS_MULTI, event_Todo_Journal_Timezone),
 
     /** */
-    FREEBUSY(XcalTags.freebusy, "FREEBUSY",
+    FREEBUSY(XcalTags.freebusy, "FREEBUSY", FreebusyPropType.class,
              DataType.PERIOD,
              IS_SINGLE, freebusyOnly),
 
     /** Geographic location */
-    GEO(XcalTags.geo, "GEO", IS_SINGLE, event_Todo),
+    GEO(XcalTags.geo, "GEO", GeoPropType.class,
+        IS_SINGLE, event_Todo),
 
     /** UTC */
-    LAST_MODIFIED(XcalTags.lastModified, "LAST-MODIFIED",
+    LAST_MODIFIED(XcalTags.lastModified, "LAST-MODIFIED", LastModifiedPropType.class,
                   DataType.DATE_TIME,
                   IS_SINGLE, event_Todo_Journal_Timezone,
                   NOT_PARAM, NOT_IMMUTABLE),
 
     /** simple location value */
-    LOCATION(XcalTags.location, "LOCATION",
+    LOCATION(XcalTags.location, "LOCATION", LocationPropType.class,
              IS_SINGLE, event_Todo),
 
     /** meeting organizer */
-    ORGANIZER(XcalTags.organizer, "ORGANIZER",
+    ORGANIZER(XcalTags.organizer, "ORGANIZER", OrganizerPropType.class,
               DataType.CUA,
               IS_SINGLE, event_Todo_Journal_Freebusy),
 
     /** % complete */
-    PERCENT_COMPLETE(XcalTags.percentComplete, "PERCENT-COMPLETE",
+    PERCENT_COMPLETE(XcalTags.percentComplete, "PERCENT-COMPLETE", PercentCompletePropType.class,
                      IS_SINGLE, todoOnly),
 
     /** Priority */
-    PRIORITY(XcalTags.priority, "PRIORITY",
+    PRIORITY(XcalTags.priority, "PRIORITY", PriorityPropType.class,
              DataType.INTEGER,
              IS_SINGLE, event_Todo),
 
     /** recurrence date/time */
-    RDATE(XcalTags.rdate, "RDATE",
+    RDATE(XcalTags.rdate, "RDATE", RdatePropType.class,
           DataType.DATE_TIME,
           IS_MULTI, event_Todo_Journal_Timezone),
 
     /** recurrenceId */
-    RECURRENCE_ID(XcalTags.recurrenceId, "RECURRENCE-ID",
+    RECURRENCE_ID(XcalTags.recurrenceId, "RECURRENCE-ID", RecurrenceIdPropType.class,
                   DataType.DATE_TIME,
                   IS_SINGLE, event_Todo_Journal_Freebusy),
 
     /** Establish relationship */
-    RELATED_TO(XcalTags.relatedTo, "RELATED-TO",
+    RELATED_TO(XcalTags.relatedTo, "RELATED-TO", RelatedToPropType.class,
                IS_MULTI, event_Todo_Journal),
 
     /** Alarm: repeat time */
-    REPEAT(XcalTags.repeat, "REPEAT",
+    REPEAT(XcalTags.repeat, "REPEAT", RepeatPropType.class,
            DataType.INTEGER,
            IS_SINGLE, alarmOnly),
 
     /** Itip */
-    REQUEST_STATUS(XcalTags.requestStatus, "REQUEST-STATUS",
+    REQUEST_STATUS(XcalTags.requestStatus, "REQUEST-STATUS", RequestStatusPropType.class,
                    IS_MULTI, event_Todo_Journal_Freebusy),
 
     /** names of resources */
-    RESOURCES(XcalTags.resources, "RESOURCES",
+    RESOURCES(XcalTags.resources, "RESOURCES", ResourcesPropType.class,
               IS_MULTI, event_Todo),
 
     /** recurrence rule */
-    RRULE (XcalTags.rrule, "RRULE", DataType.RECUR,
+    RRULE (XcalTags.rrule, "RRULE", RrulePropType.class,
+           DataType.RECUR,
            IS_MULTI, event_Todo_Journal_Timezone),
 
     /** itip sequence # */
-    SEQUENCE(XcalTags.sequence, "SEQUENCE",
+    SEQUENCE(XcalTags.sequence, "SEQUENCE", SequencePropType.class,
              DataType.INTEGER,
              IS_SINGLE, event_Todo_Journal,
              NOT_PARAM, NOT_IMMUTABLE),
 
     /** Event/task status */
-    STATUS(XcalTags.status, "STATUS",
+    STATUS(XcalTags.status, "STATUS", StatusPropType.class,
            IS_SINGLE, event_Todo_Journal),
 
     /** short summary */
-    SUMMARY(XcalTags.summary, "SUMMARY",
+    SUMMARY(XcalTags.summary, "SUMMARY", SummaryPropType.class,
             IS_SINGLE, IS_MULTI, event_Todo_Journal_Alarm),
 
     /** Alarm trigger */
-    TRIGGER(XcalTags.trigger, "TRIGGER", DataType.DURATION,
+    TRIGGER(XcalTags.trigger, "TRIGGER", TriggerPropType.class,
+            DataType.DURATION,
             IS_SINGLE, alarmOnly),
 
     /** Transparency */
-    TRANSP(XcalTags.transp, "TRANSP",
+    TRANSP(XcalTags.transp, "TRANSP", TranspPropType.class,
            IS_SINGLE, eventOnly),
 
     /** */
-    TZID(XcalTags.tzid, "TZID",
+    TZID(XcalTags.tzid, "TZID", TzidPropType.class,
          IS_SINGLE, timezoneOnly),
 
     /** */
-    TZNAME(XcalTags.tzname, "TZNAME",
+    TZNAME(XcalTags.tzname, "TZNAME", TznamePropType.class,
            IS_SINGLE, timezoneOnly),
 
     /** */
-    TZOFFSETFROM(XcalTags.tzoffsetfrom, "TZOFFSETFROM",
+    TZOFFSETFROM(XcalTags.tzoffsetfrom, "TZOFFSETFROM", TzoffsetfromPropType.class,
                  DataType.UTC_OFFSET,
                  IS_SINGLE, timezoneOnly),
 
     /** */
-    TZOFFSETTO(XcalTags.tzoffsetto, "TZOFFSETTO",
+    TZOFFSETTO(XcalTags.tzoffsetto, "TZOFFSETTO", TzoffsettoPropType.class,
                DataType.UTC_OFFSET,
                IS_SINGLE, timezoneOnly),
 
     /** */
-    TZURL(XcalTags.tzurl, "TZURL",
+    TZURL(XcalTags.tzurl, "TZURL", TzurlPropType.class,
           DataType.URI,
           IS_SINGLE, timezoneOnly),
 
     /** Unique id */
-    UID(XcalTags.uid, "UID",
+    UID(XcalTags.uid, "UID", UidPropType.class,
         IS_SINGLE, event_Todo_Journal_Freebusy),
 
     /** link to some related resource */
-    URL(XcalTags.url, "URL",
+    URL(XcalTags.url, "URL", UrlPropType.class,
         DataType.URI,
         IS_SINGLE, event_Todo_Journal_Freebusy),
 
     /** treat x-properties as a single multi-valued property */
-    XPROP(BedeworkServerTags.xprop, "XPROP",
+    XPROP(BedeworkServerTags.xprop, "XPROP", null,
           IS_MULTI, allComponents),
 
     /* -------------- Non-ical ---------------- */
 
     /** non ical */
-    COLLECTION(BedeworkServerTags.collection, "COLLECTION",
+    COLLECTION(BedeworkServerTags.collection, "COLLECTION", null,
                IS_SINGLE, event_Todo_Journal),
 
     /** non ical */
-    COST(BedeworkServerTags.cost, "COST",
+    COST(BedeworkServerTags.cost, "COST", null,
          IS_SINGLE, event_Todo),
 
     /** non ical */
-    CREATOR(BedeworkServerTags.creator, "CREATOR",
+    CREATOR(BedeworkServerTags.creator, "CREATOR", null,
             DataType.HREF,
             IS_SINGLE, event_Todo_Journal,
             NOT_PARAM, IS_IMMUTABLE),
 
     /** non ical */
-    CTAG(BedeworkServerTags.ctag, "CTAG",
+    CTAG(BedeworkServerTags.ctag, "CTAG", null,
          DataType.TEXT,
          IS_SINGLE, noComponent,
          NOT_PARAM, IS_IMMUTABLE),
 
     /** non ical */
-    DELETED(BedeworkServerTags.deleted, "DELETED",
+    DELETED(BedeworkServerTags.deleted, "DELETED", null,
             IS_SINGLE, event_Todo),
 
     /** non ical */
-    END_TYPE(BedeworkServerTags.endType, "END-TYPE",
+    END_TYPE(BedeworkServerTags.endType, "END-TYPE", null,
              IS_SINGLE, event_Todo_Journal),
 
     /** non ical */
-    ETAG(BedeworkServerTags.etag, "ETAG",
+    ETAG(BedeworkServerTags.etag, "ETAG", null,
          DataType.TEXT,
          IS_SINGLE, noComponent,
          NOT_PARAM, IS_IMMUTABLE),
 
     /** non ical */
-    ENTITY_TYPE(BedeworkServerTags.entityType, "ENTITY_TYPE",
+    ENTITY_TYPE(BedeworkServerTags.entityType, "ENTITY_TYPE", null,
                 DataType.INTEGER,
                 IS_SINGLE, event_Todo_Journal,
                 NOT_PARAM, IS_IMMUTABLE),
 
     /** non ical */
-    OWNER(BedeworkServerTags.owner, "OWNER",
+    OWNER(BedeworkServerTags.owner, "OWNER", null,
           DataType.HREF,
           IS_SINGLE, event_Todo_Journal,
           NOT_PARAM, IS_IMMUTABLE),
 
     /** treat VALARM sub-component as a property */
-    VALARM(XcalTags.valarm, "VALARM", IS_MULTI, notAlarm),
+    VALARM(XcalTags.valarm, "VALARM", AlarmComponentType.class,
+           IS_MULTI, notAlarm),
 
     /** ----------------------------- Following are parameters ----------- */
 
     /** */
-    LANG(BedeworkServerTags.language, "LANGUAGE", DataType.TEXT,
+    LANG(BedeworkServerTags.language, "LANGUAGE", LanguageParamType.class,
+         DataType.TEXT,
          IS_SINGLE, noComponent,
          IS_PARAM, NOT_IMMUTABLE),
 
     /** */
-    TZIDPAR(XcalTags.tzid, "TZID", DataType.TEXT, IS_SINGLE, noComponent,
+    TZIDPAR(XcalTags.tzid, "TZID", TzidParamType.class,
+            DataType.TEXT, IS_SINGLE, noComponent,
             IS_PARAM, NOT_IMMUTABLE),
-            ;
 
+    /** ----------------------------- X-properties in schema ----------- */
+
+    /** Cost */
+    XBEDEWORK_COST(XcalTags.xBedeworkCost, "X-BEDEWORK-COST", XBedeworkCostPropType.class,
+            IS_SINGLE, event_Todo),
+
+    /** ----------------------------- Vcalendar properties ----------- */
+
+    /** Transparency */
+    CALSCALE(XcalTags.calscale, "CALSCALE", CalscalePropType.class,
+           IS_SINGLE, vcalendarOnly),
+
+    /** Transparency */
+    METHOD(XcalTags.method, "METHOD", MethodPropType.class,
+           IS_SINGLE, vcalendarOnly),
+
+    /** Transparency */
+    PRODID(XcalTags.transp, "PRODID", ProdidPropType.class,
+           IS_SINGLE, vcalendarOnly),
+
+    /** Transparency */
+    VERSION(XcalTags.transp, "VERSION", VersionPropType.class,
+           IS_SINGLE, vcalendarOnly),
+
+     ;
+
     private QName qname;
 
     private String pname;
 
+    private Class xmlClass;
+
     private DataType ptype;
 
     /* true if the standard says it's multi */
@@ -666,12 +881,15 @@
 
     private ComponentFlags components;
 
-    private static HashMap<String, PropertyInfoIndex> pnameLookup =
+    private static Map<String, PropertyInfoIndex> pnameLookup =
       new HashMap<String, PropertyInfoIndex>();
 
-    private static HashMap<QName, PropertyInfoIndex> qnameLookup =
+    private static Map<QName, PropertyInfoIndex> qnameLookup =
       new HashMap<QName, PropertyInfoIndex>();
 
+    private static Map<Class, PropertyInfoIndex> xmlClassLookup =
+        new HashMap<Class, PropertyInfoIndex>();
+
     static {
       for (PropertyInfoIndex pii: values()) {
         String pname = pii.getPname();
@@ -681,18 +899,20 @@
         }
         pnameLookup.put(pname, pii);
 
-        QName qname = pii.getQname();
+        qnameLookup.put(pii.getQname(), pii);
 
-        qnameLookup.put(qname, pii);
+        xmlClassLookup.put(pii.xmlClass, pii);
       }
     }
 
     PropertyInfoIndex(final QName qname,
                       final String pname,
+                      final Class xmlClass,
                       final boolean multiValued,
                       final ComponentFlags components) {
       this.qname = qname;
       this.pname = pname;
+      this.xmlClass = xmlClass;
       this.components = components;
       this.multiValued = multiValued;
       dbMultiValued = multiValued;
@@ -700,30 +920,33 @@
 
     PropertyInfoIndex(final QName qname,
                       final String pname,
+                      final Class xmlClass,
                       final DataType ptype, final boolean multiValued,
                       final ComponentFlags components) {
-      this(qname, pname, multiValued, components);
+      this(qname, pname, xmlClass, multiValued, components);
       this.ptype = ptype;
     }
 
     PropertyInfoIndex(final QName qname,
                       final String pname,
+                      final Class xmlClass,
                       final boolean multiValued,
                       final boolean dbMultiValued,
                       final ComponentFlags components) {
-      this(qname, pname, DataType.TEXT, multiValued, components,
+      this(qname, pname, xmlClass, DataType.TEXT, multiValued, components,
            NOT_PARAM, NOT_IMMUTABLE);
       this.dbMultiValued = dbMultiValued;
     }
 
     PropertyInfoIndex(final QName qname,
                       final String pname,
+                      final Class xmlClass,
                       final DataType ptype,
                       final boolean multiValued,
                       final ComponentFlags components,
                       final boolean param,
                       final boolean immutable) {
-      this(qname, pname, multiValued, components);
+      this(qname, pname, xmlClass, multiValued, components);
       this.ptype = ptype;
       this.param = param;
       this.immutable = immutable;
@@ -745,6 +968,14 @@
       return pname;
     }
 
+    /** get the XML class
+     *
+     * @return class
+     */
+    public Class getXmlClass() {
+      return xmlClass;
+    }
+
     /** get the property type
      *
      * @return property type
@@ -849,6 +1080,14 @@
       return components.availableProperty;
     }
 
+    /** get the index given the XML class
+     * @param cl
+     * @return PropertyInfoIndex
+     */
+    public static PropertyInfoIndex fromXmlClass(final Class cl) {
+      return xmlClassLookup.get(cl);
+    }
+
     /** get the index given the property name
      *
      * @param val

Added: trunk/src/edu/rpi/cmt/db/hibernate/GenericEnumUserType.java
===================================================================
--- trunk/src/edu/rpi/cmt/db/hibernate/GenericEnumUserType.java	                        (rev 0)
+++ trunk/src/edu/rpi/cmt/db/hibernate/GenericEnumUserType.java	2011-08-23 19:42:24 UTC (rev 256)
@@ -0,0 +1,147 @@
+/* ********************************************************************
+    Licensed to Jasig under one or more contributor license
+    agreements. See the NOTICE file distributed with this work
+    for additional information regarding copyright ownership.
+    Jasig licenses this file to you under the Apache License,
+    Version 2.0 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a
+    copy of the License at:
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on
+    an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied. See the License for the
+    specific language governing permissions and limitations
+    under the License.
+ */
+
+package edu.rpi.cmt.db.hibernate;
+
+import org.hibernate.HibernateException;
+import org.hibernate.type.NullableType;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.usertype.UserType;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/** http://community.jboss.org/wiki/Java5EnumUserType
+ *
+ * @author Anthony Patricio
+ */
+public class GenericEnumUserType implements UserType, ParameterizedType {
+  private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "name";
+  private static final String DEFAULT_VALUE_OF_METHOD_NAME = "valueOf";
+
+  private Class<? extends Enum> enumClass;
+  private Class<?> identifierType;
+  private Method identifierMethod;
+  private Method valueOfMethod;
+  private NullableType type;
+  private int[] sqlTypes;
+
+  public void setParameterValues(final Properties parameters) {
+    String enumClassName = parameters.getProperty("enumClass");
+    try {
+      enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
+    } catch (ClassNotFoundException cfne) {
+      throw new HibernateException("Enum class not found", cfne);
+    }
+
+    String identifierMethodName = parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME);
+
+    try {
+      identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
+      identifierType = identifierMethod.getReturnType();
+    } catch (Exception e) {
+      throw new HibernateException("Failed to obtain identifier method", e);
+    }
+
+    type = (NullableType) TypeFactory.basic(identifierType.getName());
+
+    if (type == null) {
+      throw new HibernateException("Unsupported identifier type " + identifierType.getName());
+    }
+
+    sqlTypes = new int[] { type.sqlType() };
+
+    String valueOfMethodName = parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME);
+
+    try {
+      valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType });
+    } catch (Exception e) {
+      throw new HibernateException("Failed to obtain valueOf method", e);
+    }
+  }
+
+  public Class returnedClass() {
+    return enumClass;
+  }
+
+  public Object nullSafeGet(final ResultSet rs, final String[] names, final Object owner) throws HibernateException, SQLException {
+    Object identifier = type.get(rs, names[0]);
+    if (rs.wasNull()) {
+      return null;
+    }
+
+    try {
+      return valueOfMethod.invoke(enumClass, new Object[] { identifier });
+    } catch (Exception e) {
+      throw new HibernateException("Exception while invoking valueOf method '" + valueOfMethod.getName() + "' of " +
+          "enumeration class '" + enumClass + "'", e);
+    }
+  }
+
+  public void nullSafeSet(final PreparedStatement st, final Object value, final int index) throws HibernateException, SQLException {
+    try {
+      if (value == null) {
+        st.setNull(index, type.sqlType());
+      } else {
+        Object identifier = identifierMethod.invoke(value, new Object[0]);
+        type.set(st, identifier, index);
+      }
+    } catch (Exception e) {
+      throw new HibernateException("Exception while invoking identifierMethod '" + identifierMethod.getName() + "' of " +
+          "enumeration class '" + enumClass + "'", e);
+    }
+  }
+
+  public int[] sqlTypes() {
+    return sqlTypes;
+  }
+
+  public Object assemble(final Serializable cached, final Object owner) throws HibernateException {
+    return cached;
+  }
+
+  public Object deepCopy(final Object value) throws HibernateException {
+    return value;
+  }
+
+  public Serializable disassemble(final Object value) throws HibernateException {
+    return (Serializable) value;
+  }
+
+  public boolean equals(final Object x, final Object y) throws HibernateException {
+    return x == y;
+  }
+
+  public int hashCode(final Object x) throws HibernateException {
+    return x.hashCode();
+  }
+
+  public boolean isMutable() {
+    return false;
+  }
+
+  public Object replace(final Object original, final Object target, final Object owner) throws HibernateException {
+    return original;
+  }
+}

Modified: trunk/src/edu/rpi/sss/util/Util.java
===================================================================
--- trunk/src/edu/rpi/sss/util/Util.java	2011-08-11 19:57:28 UTC (rev 255)
+++ trunk/src/edu/rpi/sss/util/Util.java	2011-08-23 19:42:24 UTC (rev 256)
@@ -88,6 +88,38 @@
     }
   }
 
+  /** Given a class name return an object of that class.
+   * The class parameter is used to check that the
+   * named class is an instance of that class.
+   *
+   * @param className String class name
+   * @param cl   Class expected
+   * @return     Object checked to be an instance of that class
+   * @throws Exception
+   */
+  public static Object getObject(final String className,
+                                 final Class cl) throws Exception {
+    try {
+      Object o = Class.forName(className).newInstance();
+
+      if (o == null) {
+        throw new Exception("Class " + className + " not found");
+      }
+
+      if (!cl.isInstance(o)) {
+        throw new Exception("Class " + className +
+                            " is not a subclass of " +
+                            cl.getName());
+      }
+
+      return o;
+    } catch (Exception e) {
+      throw e;
+    } catch (Throwable t) {
+      throw new Exception(t);
+    }
+  }
+
   /** Format a message consisting of a format string
    *
    * @param fmt

Modified: trunk/src/edu/rpi/sss/util/xml/tagdefs/XcalTags.java
===================================================================
--- trunk/src/edu/rpi/sss/util/xml/tagdefs/XcalTags.java	2011-08-11 19:57:28 UTC (rev 255)
+++ trunk/src/edu/rpi/sss/util/xml/tagdefs/XcalTags.java	2011-08-23 19:42:24 UTC (rev 256)
@@ -200,6 +200,9 @@
   /**   */
   public static final QName scheduleStatus = new QName(namespace, "schedule-status");
 
+  /**   */
+  public static final QName xBedeworkUidParam = new QName(namespace, "x-bedework-uid");
+
   /* =====================================================================
                               geo
      ===================================================================== */
@@ -436,4 +439,10 @@
   /** VAVAILABILITY only */
   public static final QName busytype = new QName(namespace, "busytype");
 
+  /* =====================================================================
+                        x-properties in the schema
+     ===================================================================== */
+
+  /**   */
+  public static final QName xBedeworkCost = new QName(namespace, "x-bedework-cost");
 }



More information about the Bedework-commit mailing list