/* * Copyright (C) 2009 JavaRosa * * Licensed 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 org.openrosa.client.jr.core.model.utils; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Vector; import org.openrosa.client.jr.core.model.data.DateData; import org.openrosa.client.jr.core.model.data.DateTimeData; import org.openrosa.client.jr.core.model.data.IAnswerData; import org.openrosa.client.jr.core.model.data.StringData; import org.openrosa.client.jr.core.model.instance.TreeElement; import org.openrosa.client.jr.core.util.PropertyUtils; /** * The Question Preloader is responsible for maintaining a set of handlers which are capable * of parsing 'preload' elements, and their parameters, and returning IAnswerData objects. * * @author Clayton Sims * */ public class QuestionPreloader { /* String -> IPreloadHandler */ private Map preloadHandlers; /** * Creates a new Preloader with default handlers */ public QuestionPreloader() { preloadHandlers = new HashMap(); initPreloadHandlers(); } /** * Initializes the default preload handlers */ private void initPreloadHandlers() { IPreloadHandler date = new IPreloadHandler() { public String preloadHandled() { return "date"; } public IAnswerData handlePreload(String preloadParams) { return preloadDate(preloadParams); } public boolean handlePostProcess(TreeElement node, String params) { //do nothing return false; } }; IPreloadHandler property = new IPreloadHandler() { public String preloadHandled() { return "property"; } public IAnswerData handlePreload(String preloadParams) { return preloadProperty(preloadParams); } public boolean handlePostProcess(TreeElement node, String params) { saveProperty(params, node); return false; } }; IPreloadHandler timestamp = new IPreloadHandler() { public String preloadHandled() { return "timestamp"; } public IAnswerData handlePreload(String preloadParams) { return ("start".equals(preloadParams) ? getTimestamp() : null); } public boolean handlePostProcess(TreeElement node, String params) { if ("end".equals(params)) { node.setAnswer(getTimestamp()); return true; } else { return false; } } }; IPreloadHandler uid = new IPreloadHandler() { public String preloadHandled() { return "uid"; } public IAnswerData handlePreload(String preloadParams) { return new StringData(PropertyUtils.genGUID(25)); } public boolean handlePostProcess(TreeElement node, String params) { return false; } }; /* //TODO: Finish this up. IPreloadHandler meta = new IPreloadHandler() { public String preloadHandled() { return "meta"; } public IAnswerData handlePreload(String preloadParams) { //TODO: Ideally, we want to handle this preloader by taking in the //existing structure. Resultantly, we don't want to mess with this. //We should be enforcing that we don't. return null; } public boolean handlePostProcess(TreeElement node, String params) { Vector kids = node.getChildren(); Enumeration en = kids.elements(); while(en.hasMoreElements()) { TreeElement kid = (TreeElement)en.nextElement(); if(kid.getName().equals("uid")) { kid.setValue(new StringData(PropertyUtils.genGUID(25))); } } return true; } }; */ addPreloadHandler(date); addPreloadHandler(property); addPreloadHandler(timestamp); addPreloadHandler(uid); } /** * Adds a new preload handler to this preloader. * * @param handler an IPreloadHandler that can handle a preload type */ public void addPreloadHandler(IPreloadHandler handler) { preloadHandlers.put(handler.preloadHandled(), handler); } /** * Returns the IAnswerData preload value for the given preload type and parameters * * @param preloadType The type of the preload to be returned * @param preloadParams Parameters for the preload handler * @return An IAnswerData corresponding to a pre-loaded value for the given * Arguments. null if no preload could successfully be derived due to either * the lack of a handler, or to invalid parameters */ public IAnswerData getQuestionPreload(String preloadType, String preloadParams) { IPreloadHandler handler = (IPreloadHandler)preloadHandlers.get(preloadType); if(handler != null) { return handler.handlePreload(preloadParams); } else { System.err.println("Do not know how to handle preloader [" + preloadType + "]"); return null; } } public boolean questionPostProcess (TreeElement node, String preloadType, String params) { IPreloadHandler handler = (IPreloadHandler)preloadHandlers.get(preloadType); if(handler != null) { return handler.handlePostProcess(node, params); } else { System.err.println("Do not know how to handle preloader [" + preloadType + "]"); return false; } } /** * Preloads a DateData object for the preload type 'date' * * @param preloadParams The parameters determining the date * @return A preload date value if the parameters can be parsed, * null otherwise */ private IAnswerData preloadDate(String preloadParams) { Date d = null; if (preloadParams.equals("today")) { d = new Date(); } else if (preloadParams.substring(0, 11).equals("prevperiod-")) { Vector v = DateUtils.split(preloadParams.substring(11), "-", false); String[] params = new String[v.size()]; for (int i = 0; i < params.length; i++) params[i] = (String)v.elementAt(i); try { String type = params[0]; String start = params[1]; boolean beginning; if (params[2].equals("head")) beginning = true; else if (params[2].equals("tail")) beginning = false; else throw new RuntimeException(); boolean includeToday; if (params.length >= 4) { if (params[3].equals("x")) includeToday = true; else if (params[3].equals("")) includeToday = false; else throw new RuntimeException(); } else { includeToday = false; } int nAgo; if (params.length >= 5) { nAgo = Integer.parseInt(params[4]); } else { nAgo = 1; } d = new Date(); //DateUtils.getPastPeriodDate(new Date(), type, start, beginning, includeToday, nAgo); } catch (Exception e) { throw new IllegalArgumentException("invalid preload params for preload mode 'date'"); } } DateData data = new DateData(d); return data; } /** * Preloads a StringData object for the preload type 'property' * * @param preloadParams The parameters determining the property to be retrieved * @return A preload property value if the parameters can be parsed, * null otherwise */ private IAnswerData preloadProperty(String preloadParams) { String propname = preloadParams; //String propval = PropertyManager._().getSingularProperty(propname); //TODO ???????????????????????? String propval = null; StringData data = null; if (propval != null && propval.length() > 0) { data = new StringData(propval); } return data; } private void saveProperty (String propName, TreeElement node) { IAnswerData answer = node.getValue(); String value = (answer == null ? null : answer.getDisplayText()); if (propName != null && propName.length() > 0 && value != null && value.length() > 0){ //PropertyManager._().setProperty(propName, value); //TODO ????????????????????????? } } private DateTimeData getTimestamp() { return new DateTimeData(new Date()); } }