[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