/*
Copyright (C) 2005 Board of Regents of the University of Wisconsin
System (Univ. of Wisconsin-Madison, Trace R&D Center)
This piece of the software package, developed by the Trace Center -
University of Wisconsin is released to the public domain with only
the following restrictions:
1) That the following acknowledgement be included in the source code and
documentation for the program or package that use this code:
Parts of this program were based on reference designs developed by the
Trace Center, University of Wisconsin-Madison under funding from the
National Institute on Disability and Rehabilitation Research US Dept
of Education.
2) That this program not be modified unless it is plainly marked as modified
from the original distributed by Trace.
(NOTE: This release applies only to the files that contain this notice, not
necessarily to any other code or libraries associated with this file. Please
check individual files and libraries for the rights to use each)
This reference design was developed under funding from the National Institute
on Disability and Rehabilitation Research US Dept of Education.
THIS PIECE OF THE SOFTWARE PACKAGE IS EXPERIMENTAL/DEMONSTRATION IN NATURE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package edu.wisc.trace.urcsamples.textclient;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import edu.wisc.trace.urcsdk.base.Constants;
import edu.wisc.trace.urcsdk.client.GenericClient;
import edu.wisc.trace.urcsdk.client.IInteractor;
import edu.wisc.trace.urcsdk.client.TargetMirror;
import edu.wisc.trace.urcsdk.client.resources.EmptyResource;
import edu.wisc.trace.urcsdk.client.resources.IResource;
import edu.wisc.trace.urcsdk.client.resources.ResourceManager;
import edu.wisc.trace.urcsdk.client.uisocket.ElementRef;
import edu.wisc.trace.urcsdk.client.uisocket.UISocketMirror;
import edu.wisc.trace.urcsdk.support.UserPreferences;
/**
*
* TextDateTime is the text implementation of the DateTime
* interactor. It binds to the socket element xsd:dateTime
*
*
*
* Created on:Sept 14, 2006
* Known bugs: None
* Thread safe: Yes
*
*
* @author Hemanth Vijayan, Trace R&D Center
* @version $Revision 1.0$
*
*/
public class TextDateTime extends TextWidget {
public String label;
private boolean write;
private boolean read;
private String time, date;
private SessionPanel sp;
public TextDateTime(TextUIBuilder b, IInteractor i, GenericClient gc) {
super(b, i);
this.label = getLabel();
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsdk.client.Widget#getUIComponent()
*/
public String getUIComponent() {
String[] s = interactor.getSocketElement().getValue().toString().trim()
.split("T");
if (s.length != 2)
return label.trim() + " (not set) ";
else
return label.trim() + " (" + s[0] + " " + s[1] + ") ";
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsdk.client.Widget#updateResources()
*/
public void updateResources() {
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsdk.client.Widget#updateValue()
*/
public void updateValue() {
if (sp != null)
sp.paintSessionPanel();
}
/**
* This method adds the session panel to the textTime object. The reason for
* this is so that it will be able to access whether or not a modal dialog
* has been displayed to the user.
*
* @param sp
* SessionPanel object
*/
public void setSessionPanel(SessionPanel sp) {
this.sp = sp;
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsdk.client.Widget#setReadable(boolean)
*/
public void setReadable(boolean read) {
this.read = read;
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsamples.textclient.TextWidget#getReadable()
*/
public boolean getReadable() {
return this.read;
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsdk.client.Widget#setWriteable(boolean)
*/
public void setWriteable(boolean write) {
this.write = write;
}
/*
* (non-Javadoc)
*
* @see edu.wisc.trace.urcsdk.client.Widget#setExecutable(boolean)
*/
public void setExecutable(boolean execute) {
}
/**
* Waits for user input and performs action when entered.
*/
public void doChange() {
if (getWriteable()) {
InputStreamReader isr = new InputStreamReader(System.in);
StreamTokenizer st = new StreamTokenizer(isr);
System.out.print("Please enter value for " + label
+ " or b to go back: ");
boolean read = true;
boolean exit = false;
st.wordChars('\n', '\n');
st.wordChars(':', ':');
st.wordChars('-', '-');
st.wordChars('/', '/');
st.wordChars(',', ',');
st.eolIsSignificant(true);
TextModalDialog tmd = null;
try {
while (!exit) {
String s = "";
while (read) {
switch (st.nextToken()) {
case StreamTokenizer.TT_EOL:
if (this.sp.getDialog() == null) {
read = false;
} else {
this.sp.getDialog().getWidgetWindow("");
read = false;
exit = true;
doChange();
}
break;
case StreamTokenizer.TT_NUMBER:
if (this.sp.getDialog() == null) {
s += ((Integer) (int) st.nval).toString();
} else {
tmd = this.sp.getDialog();
tmd.getWidgetWindow(((Integer) (int) st.nval)
.toString());
read = false;
exit = true;
doChange();
}
break;
case StreamTokenizer.TT_WORD:
if (this.sp.getDialog() == null) {
s += st.sval; // Already a String
} else {
tmd = this.sp.getDialog();
tmd.getWidgetWindow(st.sval);
read = false;
exit = true;
doChange();
}
break;
default: // single character in ttype
if (this.sp.getDialog() == null) {
s += String.valueOf((char) st.ttype);
} else {
tmd = this.sp.getDialog();
tmd.getWidgetWindow(st.sval);
read = false;
exit = true;
doChange();
}
break;
}
}
if (tmd == null) {
if (s.toLowerCase().equals("b")) {
exit = true;
} else if (s.equals("?") || s.toLowerCase().equals("h")
|| s.toLowerCase().equals("help")) {
String helpString = "No help found";
if (!HelpParser.dateTime.equals(null)) {
helpString = HelpParser.dateTime;
}
read = true;
System.out.println(helpString);
System.out.print("Please enter value for " + label
+ " or b to go back: ");
} else {
String[] split = s.split(",");
if (split.length > 2 || split.length < 2) {
// incorrect input
System.out.println("Invalid entry, try again ");
System.out.print("Please enter value for "
+ label + " or b to go back: ");
read = true;
} else {
date = split[0];
time = split[1];
if (fixDate() && fixTime()) {
if (getWriteable())
interactor.getSocketElement()
.setValueRequest(
date + "T" + time);
read = true;
System.out.print("Please enter value for "
+ label + " or b to go back: ");
} else {
read = true;
System.out.print("Please enter value for "
+ label + " or b to go back: ");
}
}
// exit = true;
}
}
}
} catch (Exception e) {
logger.warning(e.getLocalizedMessage());
}
if (!exit)
doChange();
}
}
/**
* gets the label for the interactor
*
* @return String label
*/
public String getLabel() {
String lab = getText(Constants.ResourceRole.Label.toString());
if (lab.equals(""))
return interactor.getSocketElement().getId();
else
return lab;
}
/**
* returns write
*
* @return boolean write
*/
public boolean getWriteable() {
return write;
}
private boolean fixDate() {
String text = date;
String split[] = null;
XMLGregorianCalendar cal;
if (text.contains("/")) {
split = text.split("/");
}
if (text.contains("-")) {
split = text.split("-");
}
if (split == null)
return false;
if (split.length != 3)
return false;
else {
if (Integer.parseInt(split[0]) < 9)
split[0] = "0" + Integer.parseInt(split[0]);
if (Integer.parseInt(split[1]) < 9)
split[1] = "0" + Integer.parseInt(split[1]);
String month = split[0];
String date = split[1];
String year = split[2];
try {
cal = (DatatypeFactory.newInstance())
.newXMLGregorianCalendar(year + "-" + month + "-"
+ date);
} catch (DatatypeConfigurationException dce) {
logger.warning(dce.getMessage());
return false;
} catch (IllegalArgumentException iae) {
logger.warning("Incorrect DateTime input");
return false;
}
if (cal.getXMLSchemaType().equals(DatatypeConstants.DATE)) {
this.date = year + "-" + month + "-" + date;
return true;
} else
return false;
}
}
private boolean fixTime() {
String hour = "";
String minutes = "";
String seconds = "";
String ampm = "";
int h = 0;
int m = 0;
int s = 0;
String text = time;
if (text.contains(":")) {
String[] split = text.split(":");
if (split.length == 3) {
hour = split[0];
minutes = split[1];
if (split[2].contains("a")) {
split[2] = split[2].replaceAll("am", "");
split[2] = split[2].replaceAll("a", "");
ampm = "AM";
}
if (split[2].contains("p")) {
split[2] = split[2].replaceAll("pm", "");
split[2] = split[2].replaceAll("p", "");
ampm = "PM";
}
seconds = split[2];
}
if (split.length == 2) {
hour = split[0];
seconds = "00";
if (split[1].contains("a")) {
split[1] = split[1].replaceAll("am", "");
split[1] = split[1].replaceAll("a", "");
ampm = "AM";
}
if (split[1].contains("p")) {
split[1] = split[1].replaceAll("pm", "");
split[1] = split[1].replaceAll("p", "");
ampm = "PM";
}
minutes = split[1];
} else {
return false;
}
}
if (hour.length() > 2 || hour.length() < 1) {
// first char was : so hour is wrong or more than 2 numbers.
return false;
} else {
// hour is either one digit or 2.
try {
h = Integer.parseInt(hour);
} catch (NumberFormatException nfe) {
return false;
}
}
try {
m = Integer.parseInt(minutes);
} catch (NumberFormatException nfe) {
// wrong minutes input so can't be fixed
return false;
}
try {
s = Integer.parseInt(seconds);
} catch (NumberFormatException nfe) {
// wrong minutes input so can't be fixed
return false;
}
if (h > 23 || h < 0)
return false;
if (m > 59 || m < 0)
return false;
if (s > 59 || s < 0)
return false;
if (ampm.equals("pm")) {
if (h < 12)
h = h + 12;
if (h == 12)
h = 0;
else
return false;
}
if (ampm.equals("am")) {
if (h > 12)
return false;
}
if (h <= 9)
hour = "0" + h;
if (m <= 9)
minutes = "0" + m;
if (s < 9)
seconds = "0" + s;
time = hour + ":" + minutes + ":" + seconds;
return true;
}
/**
* This method gets the HelpPurpose defined in a resource sheet for the time
* interactor and returns the text in the following format. Help-Purpose :
* (string text)
*
* @return help text.
*/
public String getHelpText() {
String tmp, text = "";
if (!(tmp = getText(Constants.ResourceRole.HelpPurpose.toString()))
.equals("")) {
text = "Help-Purpose: " + tmp;
}
return text;
}
/**
* This method is the base that the getHelpText() and getLabel() call. It
* has a role parameter which passes the desired role to the resource
* manager.
*
* @param role
* @return label/help
*/
private String getText(String role) {
UserPreferences uPrefs = builder.getUrc().getPreferences();
UISocketMirror uis = interactor.getSocketElement().getSocket();
TargetMirror t = uis.getTarget();
ResourceManager rm = t.getResourceManager();
ElementRef elementRef = interactor.getSocketElement().getRef();
String valueRef = interactor.getSocketElement().getValue().toString();
valueRef = (valueRef.equals("")) ? null : valueRef;
IResource label = rm.getResource(elementRef, valueRef, true, null,
role, uPrefs);
if (label == null)
return "";
else if (label instanceof EmptyResource)
return "";
else
return label.getValue().toString();
}
}