diff --git a/lib/agrovoc_ws.jar b/lib/agrovoc_ws.jar
new file mode 100644
index 00000000..d8eb97b0
Binary files /dev/null and b/lib/agrovoc_ws.jar differ
diff --git a/lib/axis.jar b/lib/axis.jar
new file mode 100644
index 00000000..9458fa4f
Binary files /dev/null and b/lib/axis.jar differ
diff --git a/lib/commons-beanutils.jar b/lib/commons-beanutils.jar
new file mode 100644
index 00000000..b1b89c9c
Binary files /dev/null and b/lib/commons-beanutils.jar differ
diff --git a/lib/commons-discovery-0.2.jar b/lib/commons-discovery-0.2.jar
new file mode 100644
index 00000000..5db59d2e
Binary files /dev/null and b/lib/commons-discovery-0.2.jar differ
diff --git a/lib/ezmorph-1.0.4.jar b/lib/ezmorph-1.0.4.jar
new file mode 100644
index 00000000..7625af67
Binary files /dev/null and b/lib/ezmorph-1.0.4.jar differ
diff --git a/lib/json-lib-2.2.2-jdk15.jar b/lib/json-lib-2.2.2-jdk15.jar
new file mode 100644
index 00000000..27e7c7cc
Binary files /dev/null and b/lib/json-lib-2.2.2-jdk15.jar differ
diff --git a/lib/webserviceutils.jar b/lib/webserviceutils.jar
new file mode 100644
index 00000000..a7f8126b
Binary files /dev/null and b/lib/webserviceutils.jar differ
diff --git a/productMods/edit/forms/js/addConcept.js b/productMods/edit/forms/js/addConcept.js
index a80ce6a8..8202d73b 100644
--- a/productMods/edit/forms/js/addConcept.js
+++ b/productMods/edit/forms/js/addConcept.js
@@ -120,7 +120,8 @@ var addConceptForm = {
submitSearchTerm: function() {
//Get value of search term
var searchValue = this.searchTerm.val();
- var dataServiceUrl = addConceptForm.dataServiceUrl + "?searchTerm=" + encodeURIComponent(searchValue);
+ var vocabSourceValue = this.vocabSource.val();
+ var dataServiceUrl = addConceptForm.dataServiceUrl + "?searchTerm=" + encodeURIComponent(searchValue) + "&source=" + encodeURIComponent(vocabSourceValue);
$.getJSON(dataServiceUrl, function(results) {
if ( results.array.length == 0 ) {
alert("results not correct length");
diff --git a/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl b/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl
index dab3fe09..8b2ae2e7 100644
--- a/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl
+++ b/productMods/templates/freemarker/edit/forms/addAssociatedConcept.ftl
@@ -11,7 +11,7 @@
<#--This is set for testing purposes - will be retrieved dynamically from the generator later-->
-<#assign sources = [{"uri":"http://link.informatics.stonybrook.edu/umls/", "label":"UMLS"}, {"uri":"http://www.agrovoc.com", "label":"Agrovoc"}]/>
+<#assign sources = [{"uri":"http://link.informatics.stonybrook.edu/umls/", "label":"UMLS"}, {"uri":"http://www.fao.org/webservices/Agrovoc", "label":"Agrovoc"}]/>
<#assign selectedSource = "UMLS" />
Manage Concepts
@@ -117,7 +117,7 @@
diff --git a/src/edu/cornell/mannlib/semservices/bo/Concept.java b/src/edu/cornell/mannlib/semservices/bo/Concept.java
new file mode 100644
index 00000000..706d7ea4
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/bo/Concept.java
@@ -0,0 +1,104 @@
+package edu.cornell.mannlib.semservices.bo;
+
+public class Concept {
+
+ private String definedBy;
+ private String conceptId;
+ private String bestMatch;
+ private String label;
+ private String type;
+ private String definition;
+ private String uri;
+
+ /**
+ * default constructor
+ */
+ public Concept() {
+
+ }
+ /**
+ * @return the conceptId
+ */
+ public String getConceptId() {
+ return conceptId;
+ }
+ /**
+ * @param conceptId the conceptId to set
+ */
+ public void setConceptId(String conceptId) {
+ this.conceptId = conceptId;
+ }
+ /**
+ * @return the label
+ */
+ public String getLabel() {
+ return label;
+ }
+ /**
+ * @param label the label to set
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+ /**
+ * @return the type
+ */
+ public String getType() {
+ return type;
+ }
+ /**
+ * @param type the type to set
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+ /**
+ * @return the definition
+ */
+ public String getDefinition() {
+ return definition;
+ }
+ /**
+ * @param definition the definition to set
+ */
+ public void setDefinition(String definition) {
+ this.definition = definition;
+ }
+ /**
+ * @return the uri
+ */
+ public String getUri() {
+ return uri;
+ }
+ /**
+ * @param uri the uri to set
+ */
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+ /**
+ * @return the definedBy
+ */
+ public String getDefinedBy() {
+ return definedBy;
+ }
+ /**
+ * @param definedBy the definedBy to set
+ */
+ public void setDefinedBy(String definedBy) {
+ this.definedBy = definedBy;
+ }
+ /**
+ * @return the bestMatch
+ */
+ public String getBestMatch() {
+ return bestMatch;
+ }
+ /**
+ * @param bestMatch the bestMatch to set
+ */
+ public void setBestMatch(String bestMatch) {
+ this.bestMatch = bestMatch;
+ }
+
+}
diff --git a/src/edu/cornell/mannlib/semservices/bo/Day.java b/src/edu/cornell/mannlib/semservices/bo/Day.java
new file mode 100644
index 00000000..9c7bb998
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/bo/Day.java
@@ -0,0 +1,749 @@
+package edu.cornell.mannlib.semservices.bo;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import edu.cornell.mannlib.semservices.util.DateUtils;
+
+/**
+ * A time-less and immutable Date class for basic date arithmetics.
+ *
+ * @author Jacob Dreyer
+ */
+public class Day implements Comparable {
+ /** The back end calendar instance of this day. */
+ protected Calendar calendar_ = Calendar.getInstance();
+
+ /**
+ * Create a new day. The day is lenient meaning that illegal day parameters
+ * can be specified and results in a recomputed day with legal month/day
+ * values.
+ *
+ * @param year
+ * Year of new day.
+ * @param month
+ * Month of new day (0-11)
+ * @param dayOfMonth
+ * Day of month of new day (1-31)
+ */
+ public Day(int year, int month, int dayOfMonth) {
+ initialize(year, month, dayOfMonth);
+ }
+
+ /**
+ * Create a new day, specifying the year and the day of year. The day is
+ * lenient meaning that illegal day parameters can be specified and results
+ * in a recomputed day with legal month/day values.
+ *
+ * @param year
+ * Year of new day.
+ * @param dayOfYear
+ * 1=January 1, etc.
+ */
+ public Day(int year, int dayOfYear) {
+ initialize(year, Calendar.JANUARY, 1);
+ calendar_.set(Calendar.DAY_OF_YEAR, dayOfYear);
+ }
+
+ /**
+ * Create a new day representing the day of creation (according to the
+ * setting of the current machine).
+ */
+ public Day() {
+ // Now (in the current locale of the client machine)
+ Calendar calendar = Calendar.getInstance();
+
+ // Prune time part
+ initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH));
+ }
+
+ /**
+ * Create a new day based on a java.util.Calendar instance. NOTE: The time
+ * component from calendar will be pruned.
+ *
+ * @param calendar
+ * Calendar instance to copy.
+ * @throws IllegalArgumentException
+ * If calendar is null.
+ */
+ public Day(Calendar calendar) {
+ if (calendar == null)
+ throw new IllegalArgumentException("calendar cannot be null");
+
+ initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH));
+ }
+
+ /**
+ * Create a new day based on a java.util.Date instance. NOTE: The time
+ * component from date will be pruned.
+ *
+ * @param date
+ * Date instance to copy.
+ * @throws IllegalArgumentException
+ * If date is null.
+ */
+ public Day(Date date) {
+ if (date == null)
+ throw new IllegalArgumentException("date cannot be null");
+
+ // Create a calendar based on given date
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+
+ // Extract date values and use these only
+ initialize(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH));
+ }
+
+ /**
+ * Create a new day based on a time value. Time is milliseconds since
+ * "the Epoch" (1.1.1970). NOTE: The time component from time will be pruned.
+ *
+ * @param time
+ * Milliseconds since "the Epoch".
+ */
+ public Day(long time) {
+ this(new Date(time));
+ }
+
+ /**
+ * Create a new day as a copy of the specified day.
+ *
+ * @param day
+ * Day to clone.
+ * @throws IllegalArgumentException
+ * If day is null.
+ */
+ public Day(Day day) {
+ if (day == null)
+ throw new IllegalArgumentException("day cannot be null");
+
+ initialize(day.getYear(), day.getMonth(), day.getDayOfMonth());
+ }
+
+ /**
+ * Initialize the internal calendar instance.
+ *
+ * @param year
+ * Year of new day.
+ * @param month
+ * Month of new day.
+ * @param dayOfMonth
+ * Day of month of new day.
+ */
+ private void initialize(int year, int month, int dayOfMonth) {
+ calendar_.setLenient(true);
+ calendar_.setFirstDayOfWeek(Calendar.MONDAY);
+ calendar_.setTimeZone(TimeZone.getDefault());
+ calendar_.set(Calendar.YEAR, year);
+ calendar_.set(Calendar.MONTH, month);
+ calendar_.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ // Prune the time component
+ calendar_.set(Calendar.HOUR_OF_DAY, 0);
+ calendar_.set(Calendar.MINUTE, 0);
+ calendar_.set(Calendar.SECOND, 0);
+ calendar_.set(Calendar.MILLISECOND, 0);
+ }
+
+ /**
+ * A more explicit front-end to the Day() constructor which return a day
+ * object representing the day of creation.
+ *
+ * @return A day instance representing today.
+ */
+ public static Day today() {
+ return new Day();
+ }
+
+ /**
+ * Return a Calendar instance representing the same day as this instance. For
+ * use by secondary methods requiring java.util.Calendar as input.
+ *
+ * @return Calendar equivalent representing this day.
+ */
+ public Calendar getCalendar() {
+ return (Calendar) calendar_.clone();
+ }
+
+ /**
+ * Return a Date instance representing the same date as this instance. For
+ * use by secondary methods requiring java.util.Date as input.
+ *
+ * @return Date equivalent representing this day.
+ */
+ public Date getDate() {
+ return getCalendar().getTime();
+ }
+
+ /**
+ * Compare this day to the specified day. If object is not of type Day a
+ * ClassCastException is thrown.
+ *
+ * @param day
+ * Day object to compare to.
+ * @return @see Comparable#compareTo(Object)
+ * @throws IllegalArgumentException
+ * If day is null.
+ */
+ public int compareTo(Day day) {
+ if (day == null)
+ throw new IllegalArgumentException("day cannot be null");
+
+ return calendar_.getTime().compareTo(day.calendar_.getTime());
+ }
+
+ /**
+ * Return true if this day is after the specified day.
+ *
+ * @param day
+ * Day to compare to.
+ * @return True if this is after day, false otherwise.
+ * @throws IllegalArgumentException
+ * If day is null.
+ */
+ public boolean isAfter(Day day) {
+ if (day == null)
+ throw new IllegalArgumentException("day cannot be null");
+
+ return calendar_.after(day.calendar_);
+ }
+
+ /**
+ * Return true if this day is before the specified day.
+ *
+ * @param day
+ * Day to compare to.
+ * @return True if this is before day, false otherwise.
+ * @throws IllegalArgumentException
+ * If day is null.
+ */
+ public boolean isBefore(Day day) {
+ if (day == null)
+ throw new IllegalArgumentException("day cannot be null");
+
+ return calendar_.before(day.calendar_);
+ }
+
+ /**
+ * Return true if this day equals (represent the same date) as the specified
+ * day.
+ *
+ * @param object
+ * Object to compare to.
+ * @return True if this equals day, false otherwise.
+ * @throws IllegalArgumentException
+ * If day is null.
+ */
+ @Override
+ public boolean equals(Object object) {
+ Day day = (Day) object;
+
+ if (day == null)
+ throw new IllegalArgumentException("day cannot be null");
+
+ return calendar_.equals(day.calendar_);
+ }
+
+ /**
+ * Overload required as default definition of equals() has changed.
+ *
+ * @return A hash code value for this object.
+ */
+ @Override
+ public int hashCode() {
+ return calendar_.hashCode();
+ }
+
+ /**
+ * Return year of this day.
+ *
+ * @return Year of this day.
+ */
+ public int getYear() {
+ return calendar_.get(Calendar.YEAR);
+ }
+
+
+
+ /**
+ * Return month of this day. The result must be compared to Calendar.JANUARY,
+ * Calendar.FEBRUARY, etc.
+ *
+ * @return Month of this day.
+ */
+ public int getMonth() {
+ return calendar_.get(Calendar.MONTH);
+ }
+
+ public String getMonthName() {
+ switch (getMonth()) {
+ case Calendar.JANUARY:
+ return "January";
+ case Calendar.FEBRUARY:
+ return "February";
+ case Calendar.MARCH:
+ return "March";
+ case Calendar.APRIL:
+ return "April";
+ case Calendar.MAY:
+ return "May";
+ case Calendar.JUNE:
+ return "June";
+ case Calendar.JULY:
+ return "July";
+ case Calendar.AUGUST:
+ return "August";
+ case Calendar.SEPTEMBER:
+ return "September";
+ case Calendar.OCTOBER:
+ return "October";
+ case Calendar.NOVEMBER:
+ return "November";
+ case Calendar.DECEMBER:
+ return "December";
+ default:
+ assert false : "Invalid mongth: " + getMonth();
+ }
+
+ // This will never happen
+ return "";
+ }
+
+ /**
+ * Return the 1-based month number of the month of this day. 1 = January, 2 =
+ * February and so on.
+ *
+ * @return Month number of this month
+ */
+ public int getMonthNo() {
+ // It is tempting to return getMonth() + 1 but this is conceptually
+ // wrong, as Calendar month is an enumeration and the values are tags
+ // only and can be anything.
+ switch (getMonth()) {
+ case Calendar.JANUARY:
+ return 1;
+ case Calendar.FEBRUARY:
+ return 2;
+ case Calendar.MARCH:
+ return 3;
+ case Calendar.APRIL:
+ return 4;
+ case Calendar.MAY:
+ return 5;
+ case Calendar.JUNE:
+ return 6;
+ case Calendar.JULY:
+ return 7;
+ case Calendar.AUGUST:
+ return 8;
+ case Calendar.SEPTEMBER:
+ return 9;
+ case Calendar.OCTOBER:
+ return 10;
+ case Calendar.NOVEMBER:
+ return 11;
+ case Calendar.DECEMBER:
+ return 12;
+ default:
+ assert false : "Invalid mongth: " + getMonth();
+ }
+
+ // This will never happen
+ return 0;
+ }
+
+ /**
+ * Return day of month of this day. NOTE: First day of month is 1 (not 0).
+ *
+ * @return Day of month of this day.
+ */
+ public int getDayOfMonth() {
+ return calendar_.get(Calendar.DAY_OF_MONTH);
+ }
+
+ /**
+ * Return the day number of year this day represents. January 1 = 1 and so
+ * on.
+ *
+ * @return day number of year.
+ */
+ public int getDayOfYear() {
+ return calendar_.get(Calendar.DAY_OF_YEAR);
+ }
+
+ /**
+ * Return the day of week of this day. NOTE: Must be compared to
+ * Calendar.MONDAY, TUSEDAY etc.
+ *
+ * @return Day of week of this day.
+ */
+ public int getDayOfWeek() {
+ return calendar_.get(Calendar.DAY_OF_WEEK);
+ }
+
+ /**
+ * Return the day number of week of this day, where Monday=1, Tuesday=2, ...
+ * Sunday=7.
+ *
+ * @return Day number of week of this day.
+ */
+ public int getDayNumberOfWeek() {
+ return getDayOfWeek() == Calendar.SUNDAY ? 7 : getDayOfWeek()
+ - Calendar.SUNDAY;
+ }
+
+ /**
+ * Return the week number of year, this day belongs to. 1st=1 and so on.
+ *
+ * @return Week number of year of this day.
+ */
+ public int getWeekOfYear() {
+ return calendar_.get(Calendar.WEEK_OF_YEAR);
+ }
+
+ /**
+ * Return a day which is the given number of days after this day.
+ *
+ * @param nDays
+ * Number of days to add. May be negative.
+ * @return Day as requested.
+ */
+ public Day addDays(int nDays) {
+ // Create a clone
+ Calendar calendar = (Calendar) calendar_.clone();
+
+ // Add/remove the specified number of days
+ calendar.add(Calendar.DAY_OF_MONTH, nDays);
+
+ // Return new instance
+ return new Day(calendar);
+ }
+
+ /**
+ * Subtract a number of days from this day.
+ *
+ * @param nDays
+ * Number of days to subtract.
+ * @return Day as requested.
+ */
+ public Day subtractDays(int nDays) {
+ return addDays(-nDays);
+ }
+
+ /**
+ * Return a day wich is a given number of month after this day.
+ *
+ * The actual number of days added depends on the staring day. Subtracting a
+ * number of months can be done by a negative argument to addMonths() or
+ * calling subtactMonths() explicitly. NOTE: addMonth(n) m times will in
+ * general give a different result than addMonth(m*n). Add 1 month to January
+ * 31, 2005 will give February 28, 2005.
+ *
+ * @param nMonths
+ * Number of months to add.
+ * @return Day as requested.
+ */
+ public Day addMonths(int nMonths) {
+ // Create a clone
+ Calendar calendar = (Calendar) calendar_.clone();
+
+ // Add/remove the specified number of days
+ calendar.add(Calendar.MONTH, nMonths);
+
+ // Return new instance
+ return new Day(calendar);
+ }
+
+ /**
+ * Subtract a number of months from this day.
+ *
+ * @see #addMonths(int).
+ *
+ * @param nMonths
+ * Number of months to subtract.
+ * @return Day as requested.
+ */
+ public Day subtractMonths(int nMonths) {
+ return addMonths(-nMonths);
+ }
+
+ /**
+ * Return a day wich is a given number of years after this day.
+ *
+ * Add a number of years to this day. The actual number of days added depends
+ * on the starting day. Subtracting a number of years can be done by a
+ * negative argument to addYears() or calling subtractYears explicitly.
+ *
+ * @param nYears
+ * Number of years to add.
+ * @return Day as requested.
+ */
+ public Day addYears(int nYears) {
+ // Create a clone
+ Calendar calendar = (Calendar) calendar_.clone();
+
+ // Add/remove the specified number of days
+ calendar.add(Calendar.YEAR, nYears);
+
+ // Return new instance
+ return new Day(calendar);
+ }
+
+ /**
+ * Subtract a number of years from this day.
+ *
+ * @see #addYears(int).
+ *
+ * @param nYears
+ * Number of years to subtract.
+ * @return Day as requested.
+ */
+ public Day subtractYears(int nYears) {
+ return addYears(-nYears);
+ }
+
+ /**
+ * Return the number of days in the year of this day.
+ *
+ * @return Number of days in this year.
+ */
+ public int getDaysInYear() {
+ return calendar_.getActualMaximum(Calendar.DAY_OF_YEAR);
+ }
+
+ /**
+ * Return true if the year of this day is a leap year.
+ *
+ * @return True if this year is a leap year, false otherwise.
+ */
+ public boolean isLeapYear() {
+ return getDaysInYear() == calendar_.getMaximum(Calendar.DAY_OF_YEAR);
+ }
+
+ /**
+ * Return true if the specified year is a leap year.
+ *
+ * @param year
+ * Year to check.
+ * @return True if specified year is leap year, false otherwise.
+ */
+ public static boolean isLeapYear(int year) {
+ return (new Day(year, Calendar.JANUARY, 1)).isLeapYear();
+ }
+
+ /**
+ * Return the number of days in the month of this day.
+ *
+ * @return Number of days in this month.
+ */
+ public int getDaysInMonth() {
+ return calendar_.getActualMaximum(Calendar.DAY_OF_MONTH);
+ }
+
+
+
+ /**
+ * Get default locale name of this day ("Monday", "Tuesday", etc.
+ *
+ * @return Name of day.
+ */
+ public String getDayName() {
+ switch (getDayOfWeek()) {
+ case Calendar.MONDAY:
+ return "Monday";
+ case Calendar.TUESDAY:
+ return "Tuesday";
+ case Calendar.WEDNESDAY:
+ return "Wednesday";
+ case Calendar.THURSDAY:
+ return "Thursday";
+ case Calendar.FRIDAY:
+ return "Friday";
+ case Calendar.SATURDAY:
+ return "Saturday";
+ case Calendar.SUNDAY:
+ return "Sunday";
+ default:
+ assert false : "Invalid day of week: " + getDayOfWeek();
+ }
+
+ // This will never happen
+ return null;
+ }
+
+ /**
+ * Get default locale name of this day ("Monday", "Tuesday", etc.
+ *
+ * @return Name of day.
+ */
+ public String getShortDayName() {
+ switch (getDayOfWeek()) {
+ case Calendar.MONDAY:
+ return "Mon";
+ case Calendar.TUESDAY:
+ return "Tue";
+ case Calendar.WEDNESDAY:
+ return "Wed";
+ case Calendar.THURSDAY:
+ return "Thu";
+ case Calendar.FRIDAY:
+ return "Fri";
+ case Calendar.SATURDAY:
+ return "Sat";
+ case Calendar.SUNDAY:
+ return "Sun";
+ default:
+ assert false : "Invalid day of week: " + getDayOfWeek();
+ }
+
+ // This will never happen
+ return null;
+ }
+
+ /**
+ * Return number of days between two days. The method always returns a
+ * positive number of days.
+ *
+ * @param day
+ * The day to compare to.
+ * @return Number of days between this and day.
+ * @throws IllegalArgumentException
+ * If day is null.
+ */
+ public int daysBetween(Day day) {
+ if (day == null)
+ throw new IllegalArgumentException("day cannot be null");
+
+ long millisBetween = Math.abs(calendar_.getTime().getTime()
+ - day.calendar_.getTime().getTime());
+ return (int) Math.round(millisBetween / (1000 * 60 * 60 * 24));
+ }
+
+ /**
+ * Find the n'th xxxxday of s specified month (for instance find 1st sunday
+ * of May 2006; findNthOfMonth (1, Calendar.SUNDAY, Calendar.MAY, 2006);
+ * Return null if the specified day doesn't exists.
+ *
+ * @param n
+ * Nth day to look for.
+ * @param dayOfWeek
+ * Day to look for (Calendar.XXXDAY).
+ * @param month
+ * Month to check (Calendar.XXX).
+ * @param year
+ * Year to check.
+ * @return Required Day (or null if non-existent)
+ * @throws IllegalArgumentException
+ * if dyaOfWeek parameter doesn't represent a valid day.
+ */
+ public static Day getNthOfMonth(int n, int dayOfWeek, int month, int year) {
+ // Validate the dayOfWeek argument
+
+ if (dayOfWeek < 1 || dayOfWeek > 7)
+ throw new IllegalArgumentException("Invalid day of week: " + dayOfWeek);
+
+ Day first = new Day(year, month, 1);
+
+ int offset = dayOfWeek - first.getDayOfWeek();
+ if (offset < 0)
+ offset = 7 + offset;
+
+ int dayNo = (n - 1) * 7 + offset + 1;
+
+ return dayNo > first.getDaysInMonth() ? null
+ : new Day(year, month, dayNo);
+ }
+
+ /**
+ * Find the first of a specific day in a given month. For instance first
+ * Tuesday of May: getFirstOfMonth(Calendar.TUESDAY, Calendar.MAY, 2005);
+ *
+ * @param dayOfWeek
+ * Weekday to get.
+ * @param month
+ * Month of day to get.
+ * @param year
+ * Year of day to get.
+ * @return The requested day.
+ */
+ public static Day getFirstOfMonth(int dayOfWeek, int month, int year) {
+ return Day.getNthOfMonth(1, dayOfWeek, month, year);
+ }
+
+ /**
+ * Find the last of a specific day in a given month. For instance last
+ * Tuesday of May: getLastOfMonth (Calendar.TUESDAY, Calendar.MAY, 2005);
+ *
+ * @param dayOfWeek
+ * Weekday to get.
+ * @param month
+ * Month of day to get.
+ * @param year
+ * Year of day to get.
+ * @return The requested day.
+ */
+ public static Day getLastOfMonth(int dayOfWeek, int month, int year) {
+ Day day = Day.getNthOfMonth(5, dayOfWeek, month, year);
+ return day != null ? day : Day.getNthOfMonth(4, dayOfWeek, month, year);
+ }
+
+ public String getFormattedString(String fmt) {
+ return DateUtils.getFormattedDate(calendar_.getTime(), fmt);
+ }
+
+ /**
+ * Return a scratch string representation of this day. Used for debugging
+ * only. The format of the day is yyyy-mm-dd
+ *
+ * @return A string representation of this day.
+ */
+ @Override
+ public String toString() {
+ StringBuffer s = new StringBuffer();
+ s.append(getYear());
+ s.append('-');
+ if (getMonth() < 9)
+ s.append('0');
+ s.append(getMonth() + 1);
+ s.append('-');
+ if (getDayOfMonth() < 10)
+ s.append('0');
+ s.append(getDayOfMonth());
+ return s.toString();
+ }
+
+ /**
+ * Testing this class.
+ *
+ * @param arguments
+ * Not used.
+ */
+ public static void main(String[] arguments) {
+ // This proves that there are 912 days between the two major
+ // terrorist attacks, not 911 as is common knowledge.
+ Day september11 = new Day(2001, Calendar.SEPTEMBER, 11);
+ Day march11 = new Day(2004, Calendar.MARCH, 11);
+ System.out.println(september11.daysBetween(march11));
+
+ // This proves that Kennedy was president for 1037 days,
+ // not 1000 as is the popular belief nor 1036 which is the
+ // bluffers reply. Nerds knows when to add one...
+ Day precidency = new Day(1961, Calendar.JANUARY, 20);
+ Day assasination = new Day(1963, Calendar.NOVEMBER, 22);
+ System.out.println(precidency.daysBetween(assasination) + 1);
+
+ // Niel Armstrong walked the moon on a Sunday
+ Day nielOnMoon = new Day(1969, Calendar.JULY, 20);
+ System.out.println("Niel Armstron walked on the moon on "+ nielOnMoon.getDayName());
+
+ // Find last tuesdays for 2005
+ for (int i = 0; i < 12; i++) {
+ Day tuesday = Day.getLastOfMonth(Calendar.TUESDAY, i, 2005);
+ System.out.println(tuesday);
+ }
+ }
+}
diff --git a/src/edu/cornell/mannlib/semservices/bo/Time.java b/src/edu/cornell/mannlib/semservices/bo/Time.java
new file mode 100644
index 00000000..6723947e
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/bo/Time.java
@@ -0,0 +1,257 @@
+package edu.cornell.mannlib.semservices.bo;
+
+import java.util.Date;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A class representing a moment in time. Extends Day which represents the day
+ * of the moment, and defines the time within the day to millisecond accuracy.
+ *
+ * @author Jacob Dreyer (jacob.dreyer@geosoft.no)
+ */
+public class Time extends Day {
+ protected final Log logger = LogFactory.getLog(getClass());
+
+ protected static final Log staticlogger = LogFactory.getLog(Time.class);
+
+ /**
+ * Instantiate a Time object. The time is lenient meaning that illegal day
+ * parameters can be specified and results in a recomputed day with legal
+ * month/day values.
+ *
+ * @param year Year of this time
+ * @param month Month of this time
+ * @param dayOfMonth Day of month of this time.
+ * @param hourOfDay Hours of this time [0-23]
+ * @param minutes Minutes of this time [0-23]
+ * @param seconds Seconds of this time [0-23]
+ */
+ public Time(int year, int month, int dayOfMonth, int hourOfDay, int minutes,
+ int seconds) {
+ super(year, month, dayOfMonth);
+ setHourOfDay(hourOfDay);
+ setMinutes(minutes);
+ setSeconds(seconds);
+ }
+
+ /**
+ * Constructor
+ * @param day
+ * @param hourOfDay
+ * @param minutes
+ * @param seconds
+ */
+ public Time(Day day, int hourOfDay, int minutes, int seconds) {
+ this(day.getYear(), day.getMonth(), day.getDayOfMonth(), hourOfDay,
+ minutes, seconds);
+ }
+
+
+ /**
+ * Constructor
+ * @param hourOfDay
+ * @param minutes
+ * @param seconds
+ */
+ public Time(int hourOfDay, int minutes, int seconds) {
+ this(new Day(), hourOfDay, minutes, seconds);
+ }
+
+ /**
+ * Constructor
+ */
+ public Time() {
+ calendar_ = new GregorianCalendar(); // Now
+ }
+
+ // end of constructors
+
+ // Get Methods
+
+ public Date getDay() {
+ return calendar_.getTime();
+ }
+
+ public int getHour() {
+ return calendar_.get(Calendar.HOUR);
+ }
+
+ public int getHourOfDay() {
+ return calendar_.get(Calendar.HOUR_OF_DAY);
+ }
+
+ public int getMinutes() {
+ return calendar_.get(Calendar.MINUTE);
+ }
+
+ public int getSeconds() {
+ return calendar_.get(Calendar.SECOND);
+ }
+
+ public int getMilliSeconds() {
+ return calendar_.get(Calendar.MILLISECOND);
+ }
+
+ public int getAmPm() {
+ return calendar_.get(Calendar.AM_PM);
+ }
+
+ // set Methods
+
+ public void setDay(Day day) {
+ setYear(day.getYear());
+ setMonth(day.getMonth());
+ setDayOfMonth(day.getDayOfMonth());
+ }
+
+ public void setYear(int year) {
+ calendar_.set(Calendar.YEAR, year);
+ }
+
+ public void setMonth(int month) {
+ calendar_.set(Calendar.MONTH, month);
+ }
+
+ public void setDayOfMonth(int dayOfMonth) {
+ calendar_.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+ }
+
+ public void setHourOfDay(int hourOfDay) {
+ calendar_.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ }
+
+ public void setHour(int hour) {
+ calendar_.set(Calendar.HOUR, hour);
+ }
+
+ public void setAmPm(int amPm) {
+ calendar_.set(Calendar.AM_PM, amPm);
+ }
+
+ public void setMinutes(int minutes) {
+ calendar_.set(Calendar.MINUTE, minutes);
+ }
+
+ public void setSeconds(int seconds) {
+ calendar_.set(Calendar.SECOND, seconds);
+ }
+
+ public void setMilliSeconds(int milliSeconds) {
+ calendar_.set(Calendar.MILLISECOND, milliSeconds);
+ }
+
+ // Time modification methods
+
+ public void addHours(int nHours) {
+ calendar_.add(Calendar.HOUR_OF_DAY, nHours);
+ }
+
+ public void addMinutes(int nMinutes) {
+ calendar_.add(Calendar.MINUTE, nMinutes);
+ }
+
+ public void addSeconds(int nSeconds) {
+ calendar_.add(Calendar.SECOND, nSeconds);
+ }
+
+ public void addMilliSeconds(int nMilliSeconds) {
+ calendar_.add(Calendar.MILLISECOND, nMilliSeconds);
+ }
+
+ public void subtractHours(int nHours) {
+ addHours(-nHours);
+ }
+
+ public void subtractMinutes(int nMinutes) {
+ addMinutes(-nMinutes);
+ }
+
+ public void subtractSeconds(int nSeconds) {
+ addSeconds(-nSeconds);
+ }
+
+ // Time test methods
+
+ public boolean isAfter(Time time) {
+ return calendar_.after(time.calendar_);
+ }
+
+ public boolean isBefore(Time time) {
+ return calendar_.before(time.calendar_);
+ }
+
+ public boolean equals(Time time) {
+ return calendar_.equals(time.calendar_);
+ }
+
+ // Time difference methods
+
+ public long milliSecondsBetween(Time time) {
+ long millisBetween = calendar_.getTime().getTime()
+ - time.calendar_.getTime().getTime();
+ return millisBetween;
+ }
+
+ public double secondsBetween(Time time) {
+ long millisBetween = calendar_.getTime().getTime()
+ - time.calendar_.getTime().getTime();
+ return millisBetween / 1000;
+ }
+
+ public double minutesBetween(Time time) {
+ long millisBetween = calendar_.getTime().getTime()
+ - time.calendar_.getTime().getTime();
+ return millisBetween / (1000 * 60);
+ }
+
+ public double hoursBetween(Time time) {
+ long millisBetween = calendar_.getTime().getTime()
+ - time.calendar_.getTime().getTime();
+ return millisBetween / (1000 * 60 * 60);
+ }
+
+ // Display methods
+
+ public String toString() {
+ StringBuffer string = new StringBuffer();
+
+ if (getHour() == 0) {
+ string.append("12"); // display "12" for midnight
+ } else {
+ string.append(getHour());
+ }
+ string.append(':');
+ if (getMinutes() < 10)
+ string.append('0');
+ string.append(getMinutes());
+
+ if (getAmPm() == Calendar.AM) {
+ string.append(" AM");
+ } else {
+ string.append(" PM");
+ }
+ return string.toString();
+ }
+
+ // Misc. methods
+
+ public static Time getTimeFromSqlTime(java.sql.Time sqlTime) {
+ // staticlogger.info("sqlTime "+ sqlTime.toString());
+ long ms = sqlTime.getTime();
+ java.util.Calendar gcal = GregorianCalendar.getInstance();
+ gcal.setTime(new Date(ms));
+ Time time = new Time(gcal.get(Calendar.HOUR_OF_DAY), gcal
+ .get(Calendar.MINUTE), gcal.get(Calendar.SECOND));
+ return time;
+ }
+
+ public static void main(String args[]) {
+ Time time = new Time(12, 00, 00);
+ System.out.println(time);
+ }
+}
diff --git a/src/edu/cornell/mannlib/semservices/service/ExternalConceptService.java b/src/edu/cornell/mannlib/semservices/service/ExternalConceptService.java
new file mode 100644
index 00000000..a5cf2988
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/service/ExternalConceptService.java
@@ -0,0 +1,11 @@
+package edu.cornell.mannlib.semservices.service;
+
+import java.util.List;
+
+import edu.cornell.mannlib.semservices.bo.Concept;
+
+public interface ExternalConceptService {
+ // this is the only method that needs to be exposed
+ List processResults(String term);
+
+}
diff --git a/src/edu/cornell/mannlib/semservices/service/impl/AgrovocService.java b/src/edu/cornell/mannlib/semservices/service/impl/AgrovocService.java
new file mode 100644
index 00000000..45ffe84b
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/service/impl/AgrovocService.java
@@ -0,0 +1,494 @@
+package edu.cornell.mannlib.semservices.service.impl;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.rpc.ServiceException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.fao.gilw.aims.webservices.AgrovocWS;
+import org.fao.gilw.aims.webservices.AgrovocWSServiceLocator;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import edu.cornell.mannlib.semservices.bo.Concept;
+import edu.cornell.mannlib.semservices.service.ExternalConceptService;
+import edu.cornell.mannlib.semservices.util.XMLUtils;
+
+public class AgrovocService implements ExternalConceptService {
+ protected final Log logger = LogFactory.getLog(getClass());
+ private java.lang.String AgrovocWS_address = "http://www.fao.org/webservices/AgrovocWS";
+
+ public List processResults(String term) {
+ List conceptList = new ArrayList();
+
+ String termcode;
+ try {
+ termcode = getTermcodeByTerm(term);
+ } catch (Exception e1) {
+ logger.error("Could not get termcode from service", e1);
+ return null;
+ }
+
+ String format = "SKOS";
+ // if the termcode is null it means that either the service is not responding
+ // or there was not a match for the string
+ //System.out.println("Got termcode: "+termcode);
+
+ String results = getConceptInfoByTermcodeXML(termcode, format);
+
+ //XMLUtils.prettyPrint(results);
+
+ try {
+ Document doc = XMLUtils.parse(results);
+ String prefLabelQuery = "child::*[@xml:lang='EN']";
+ NodeList nodes = doc.getElementsByTagName("skos:Concept");
+ //System.out.println("Found this many nodes: "+ nodes.getLength());
+ for (int i=0; i < nodes.getLength(); i++) {
+
+ Node node = nodes.item(i);
+ //XMLUtils.serializeNode(node); System.out.println();
+
+ Concept concept = new Concept();
+ concept.setDefinedBy("Agrovoc");
+ concept.setConceptId(termcode);
+
+ NamedNodeMap attrs = node.getAttributes();
+ Attr idAttr = (Attr) attrs.getNamedItem("rdf:about");
+ String conceptUri = idAttr.getTextContent();
+ concept.setUri(conceptUri);
+
+ Node prefLabelNode = XMLUtils.getNodeWithXpath(node, prefLabelQuery);
+ if (prefLabelNode != null) {
+ String prefLabel = prefLabelNode.getTextContent();
+ concept.setLabel(prefLabel);
+ }
+ conceptList.add(concept);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (SAXException e) {
+ e.printStackTrace();
+ } catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ }
+ return conceptList;
+ //JSONObject jsonObject = null;
+ //jsonObject = BeanToJsonSerializer.serializeToJsonObject(conceptList);
+ //return jsonObject.toString();
+ }
+
+
+ protected String getAgrovocLanguages() {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getAgrovocLanguages();
+ } catch (ServiceException e) {
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getTermcodeByTerm(String term) throws Exception {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermcodeByTerm(term);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ throw e;
+ } catch (RemoteException e) {
+ logger.error("remote exception", e);
+ throw e;
+ } catch (MalformedURLException e) {
+ logger.error("malformed URL exception", e);
+ throw e;
+ }
+ return result;
+ }
+
+ protected String getTermcodeByTermXML(String term, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermcodeByTermXML(term, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ protected String getTermByLanguage(int termcode, String language) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermByLanguage(termcode, language);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ protected String getTermByLanguageXML(int termcode, String language, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermByLanguageXML(termcode, language, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getTermsListByLanguage2(String termcodes, String language, String sep) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermsListByLanguage2(termcodes, language, sep);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ protected String getTermsListByLanguageXML(String termcodes, String language, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermsListByLanguageXML(termcodes, language, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getAllLabelsByTermcode2(int termcode, String sep) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getAllLabelsByTermcode2(termcode, sep);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getAllLabelsByTermcodeXML(int termcode, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getAllLabelsByTermcodeXML(termcode, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String simpleSearchByMode2(String term, String mode, String sep ) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.simpleSearchByMode2(term, mode, sep);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String simpleSearchByModeXML(String term, String mode, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.simpleSearchByModeXML(term, mode, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String searchByTerm2(String term, String sep) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.searchByTerm2(term, sep);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String searchByTermXML(String term, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.searchByTermXML(term, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String searchCategoryByMode(String term, String lang, String schemeid, String mode, String sep) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.searchCategoryByMode(term, lang, schemeid, mode, sep);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String searchCategoryByModeXML(String term, String mode, String schemeid, String lang, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.searchCategoryByModeXML(term, mode, schemeid, lang, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String[] getConceptInfoByTermcode(String termcode) {
+ String result[] = null;
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getConceptInfoByTermcode(termcode);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getConceptInfoByTermcodeXML(String termcode, String format) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getConceptInfoByTermcodeXML(termcode, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String[] getDefinitions(int termcode, String lang) {
+ String[] result = null;
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getDefinitions(termcode, lang);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getDefinitionsXML(int termcode, String lang, String format) {
+ String result = null;
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getDefinitionsXML(termcode, lang, format);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getTermExpansion(String aQuery, String langugage) {
+ String result = new String();
+ AgrovocWSServiceLocator locator = new AgrovocWSServiceLocator();
+ try {
+ URL url = new URL(AgrovocWS_address);
+ AgrovocWS agrovoc_service = locator.getAgrovocWS(url);
+ result = agrovoc_service.getTermExpansion(aQuery, langugage);
+ } catch (ServiceException e) {
+ logger.error("service exception", e);
+ e.printStackTrace();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ protected String getWsdl() {
+ String result = new String();
+ try {
+
+ StringWriter sw = new StringWriter();
+ URL rss = new URL(AgrovocWS_address + "?wsdl");
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(rss.openStream()));
+ String inputLine;
+ while ((inputLine = in.readLine()) != null) {
+ sw.write(inputLine);
+ }
+ in.close();
+
+ result = sw.toString();
+
+ } catch (Exception ex) {
+ logger.error("error occurred in servlet", ex);
+ }
+ return result;
+ }
+}
diff --git a/src/edu/cornell/mannlib/semservices/service/impl/UMLSService.java b/src/edu/cornell/mannlib/semservices/service/impl/UMLSService.java
new file mode 100644
index 00000000..f6df7fe2
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/service/impl/UMLSService.java
@@ -0,0 +1,152 @@
+package edu.cornell.mannlib.semservices.service.impl;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+import net.sf.json.JSONSerializer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import edu.cornell.mannlib.semservices.bo.Concept;
+import edu.cornell.mannlib.semservices.service.ExternalConceptService;
+
+/**
+ * @author jaf30
+ *
+ */
+public class UMLSService implements ExternalConceptService {
+ protected final Log logger = LogFactory.getLog(getClass());
+ private static final String submissionUrl = "http://link.informatics.stonybrook.edu/MeaningLookup/MlServiceServlet?";
+ private static final String baseUri = "http://link.informatics.stonybrook.edu/umls/CUI/";
+
+ public List processResults(String term) {
+ String results = null;
+ String dataUrl = submissionUrl + "textToProcess="
+ + URLEncoder.encode(term) + "&format=json";
+
+ try {
+
+ StringWriter sw = new StringWriter();
+ URL rss = new URL(dataUrl);
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(rss.openStream()));
+ String inputLine;
+ while ((inputLine = in.readLine()) != null) {
+ sw.write(inputLine);
+ }
+ in.close();
+
+ results = sw.toString();
+
+ } catch (Exception ex) {
+ logger.error("error occurred in servlet", ex);
+ return null;
+ }
+ //System.out.println("results before processing: "+results);
+ List conceptList = processOutput(results);
+ return conceptList;
+ }
+
+ /**
+ * @param results
+ * @return
+ */
+ private List processOutput(String results) {
+
+ List conceptList = new ArrayList();
+ List bestMatchIdList = new ArrayList();
+ String bestMatchId = new String();
+ try {
+ JSONObject json = (JSONObject) JSONSerializer.toJSON( results );
+
+ if (json.has("Best Match")) {
+ //System.out.println("Best Match");
+
+ JSONArray bestMatchArray = json.getJSONArray("Best Match");
+ int len = bestMatchArray.size();
+ if (len > 1) {
+ System.out.println("Found this many best matches: "+ len);
+ }
+ int i;
+ for (i = 0; i < len; i++) {
+ JSONObject o = bestMatchArray.getJSONObject(i);
+ //System.out.println(o.toString());
+ Concept concept = new Concept();
+ concept.setDefinedBy("UMLS");
+ concept.setBestMatch("true");
+ String cui = getJsonValue(o, "CUI");
+ bestMatchIdList.add(cui);
+
+ concept.setConceptId(cui);
+ concept.setLabel(getJsonValue(o, "label"));
+ concept.setType(getJsonValue(o, "type"));
+ concept.setDefinition(getJsonValue(o, "definition"));
+ concept.setUri(baseUri + cui);
+ conceptList.add(concept);
+ }
+ }
+ if (json.has("All")) {
+
+ JSONArray allArray = json.getJSONArray("All");
+ int len = allArray.size();
+ //System.out.println("size of best match array: "+ len);
+ int i;
+ for (i = 0; i < len; i++) {
+ JSONObject o = allArray.getJSONObject(i);
+ //System.out.println(o.toString());
+ Concept concept = new Concept();
+ concept.setDefinedBy("UMLS");
+ String cui = getJsonValue(o, "CUI");
+ concept.setConceptId(cui);
+
+ concept.setLabel(getJsonValue(o, "label"));
+ concept.setType(getJsonValue(o, "type"));
+ concept.setDefinition(getJsonValue(o, "definition"));
+ concept.setUri(baseUri + cui);
+ // prevent duplicate concepts in list
+ if (! bestMatchIdList.contains(cui)) {
+ concept.setBestMatch("false");
+ conceptList.add(concept);
+ }
+ }
+ }
+ } catch (Exception ex ) {
+ ex.printStackTrace();
+ logger.error("Could not get concepts", ex);
+ }
+ return conceptList;
+
+ //
+ // now serialize the list of Concepts to a JSON String
+ //
+ //JSONObject jsonObject = null;
+ //jsonObject = BeanToJsonSerializer.serializeToJsonObject(conceptList);
+ //System.out.println(jsonObject.toString());
+ //return jsonObject.toString();
+
+ }
+
+
+ /**
+ * Get a string from a json object or an empty string if there is no value for the given key
+ * @param obj
+ * @param key
+ * @return
+ */
+ protected String getJsonValue(JSONObject obj, String key) {
+ if (obj.has(key)) {
+ return obj.getString(key);
+ } else {
+ return new String("");
+ }
+ }
+
+}
diff --git a/src/edu/cornell/mannlib/semservices/util/ClassUtils.java b/src/edu/cornell/mannlib/semservices/util/ClassUtils.java
new file mode 100644
index 00000000..457734c2
--- /dev/null
+++ b/src/edu/cornell/mannlib/semservices/util/ClassUtils.java
@@ -0,0 +1,152 @@
+/*
+ * $Id$
+ * CONFIDENTIAL AND PROPRIETARY. ? 2007 Revolution Health Group LLC. All rights reserved.
+ * This source code may not be disclosed to others, used or reproduced without the written permission of Revolution Health Group.
+ *
+ */
+package edu.cornell.mannlib.semservices.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+
+public class ClassUtils {
+ public static final String VERSION = "$Rev$";
+ private static final Logger LOG = Logger.getLogger(ClassUtils.class);
+
+ private ClassUtils() {}
+
+ @SuppressWarnings("unchecked")
+ public static Method[] getMethods(Class> clazz) {
+ if (Proxy.isProxyClass(clazz) && clazz.getInterfaces().length > 0 ) {
+ return clazz.getInterfaces()[0].getDeclaredMethods();
+ }
+
+ ArrayList methods = new ArrayList();
+ Class> interfaceClass = clazz;
+ // only change our classes
+ if ((interfaceClass.getPackage().getName().indexOf("java") != 0) && (interfaceClass != null)) {
+ if (!interfaceClass.isInterface()) {
+ Class[] interfaces = interfaceClass.getInterfaces();
+ for (Class interfaceTemp : interfaces) {
+ if (interfaceTemp.isInterface()) {
+ methods.addAll(Arrays.asList(interfaceTemp.getMethods()));
+ }
+ }
+ } else {
+ methods.addAll(Arrays.asList(interfaceClass.getMethods()));
+ }
+ }
+
+ if (methods.isEmpty()) {
+ methods.addAll(Arrays.asList(clazz.getDeclaredMethods()));
+ }
+
+ return methods.toArray(new Method[methods.size()]);
+ }
+
+ public static Object findEnumConstant(Class