From 3beba5fd39a5d60ba5b87064ddf11dea30b78413 Mon Sep 17 00:00:00 2001 From: zapata Date: Mon, 23 Jun 2003 15:24:06 +0000 Subject: [PATCH] producer abort + timezone support --- bundles/admin_en.properties | 3 +- source/default.properties | 5 + .../entity/adapter/EntityAdapterDefinition.java | 119 +++---- source/mir/misc/StringUtil.java | 378 +++------------------ source/mir/producer/NodedProducer.java | 18 +- source/mir/producer/Producer.java | 24 +- source/mir/servlet/ServletModule.java | 16 +- source/mir/storage/Database.java | 54 ++- source/mir/util/DateToMapAdapter.java | 70 ---- source/mir/util/GeneratorFormatAdapters.java | 150 +++++++- source/mir/util/HTTPRequestParser.java | 34 +- source/mir/util/JDBCStringRoutines.java | 4 +- source/mircoders/global/Abuse.java | 55 +-- source/mircoders/global/JobQueue.java | 314 +++++++++++------ source/mircoders/global/ProducerEngine.java | 127 +++---- .../basic/MirBasicDataModelLocalizer.java | 10 +- .../basic/MirBasicProducerAssistantLocalizer.java | 5 +- source/mircoders/servlet/ServletHelper.java | 2 +- .../mircoders/servlet/ServletModuleProducer.java | 38 ++- templates/admin/abuse.log.template | 2 +- templates/admin/content.template | 4 +- templates/admin/producerqueue.template | 38 ++- web/style/admin.css | 12 + 23 files changed, 701 insertions(+), 781 deletions(-) delete mode 100755 source/mir/util/DateToMapAdapter.java diff --git a/bundles/admin_en.properties b/bundles/admin_en.properties index a17f56e0..3c20519e 100755 --- a/bundles/admin_en.properties +++ b/bundles/admin_en.properties @@ -1,6 +1,6 @@ ########## admin ########## # language: english -# $Id: admin_en.properties,v 1.48.2.2 2003/06/21 04:02:08 zapata Exp $ +# $Id: admin_en.properties,v 1.48.2.3 2003/06/23 15:24:06 zapata Exp $ languagename=English @@ -389,6 +389,7 @@ producer.job.abort = abort producer.job.empty = Queue is empty producer.job.runningtime = Running time +producer.jobqueue.canceljobs = Cancel selected jobs producer.jobqueue.title = Current jobs producer.jobqueue.refresh = refresh producer.producerlist.title = Add a new job diff --git a/source/default.properties b/source/default.properties index 8a2f18c8..b5487bb5 100755 --- a/source/default.properties +++ b/source/default.properties @@ -388,6 +388,11 @@ Mir.DefaultEncoding=UTF8 # don't change this unless... Mir.DefaultHTMLCharset=UTF-8 +# Default timezone to display times in in admin, producers +# +# Leave empty to use the system's default +Mir.DefaultTimezone= + diff --git a/source/mir/entity/adapter/EntityAdapterDefinition.java b/source/mir/entity/adapter/EntityAdapterDefinition.java index 8162bb98..bb132a52 100755 --- a/source/mir/entity/adapter/EntityAdapterDefinition.java +++ b/source/mir/entity/adapter/EntityAdapterDefinition.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mir.entity.adapter; @@ -32,11 +32,12 @@ package mir.entity.adapter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; -import java.util.HashMap; +import java.util.*; import java.util.Map; import mir.entity.Entity; -import mir.util.DateToMapAdapter; +import mir.util.GeneratorFormatAdapters; +import mir.misc.*; public class EntityAdapterDefinition { Map calculatedFields; @@ -61,12 +62,12 @@ public class EntityAdapterDefinition { calculatedFields.put(aFieldName, aField); } - public void addMirDateField(String aDestinationFieldName, String aSourceFieldName) { - addCalculatedField(aDestinationFieldName, new MirDateField(aSourceFieldName)); + public void addMirDateField(String aDestinationFieldName, String aSourceFieldName, String aDefaultTimezone) { + addCalculatedField(aDestinationFieldName, new MirDateField(aSourceFieldName, aDefaultTimezone)); } - public void addDBDateField(String aDestinationFieldName, String aSourceFieldName) { - addCalculatedField(aDestinationFieldName, new DBDateField(aSourceFieldName)); + public void addDBDateField(String aDestinationFieldName, String aSourceFieldName, String aDefaultTimezone) { + addCalculatedField(aDestinationFieldName, new DBDateField(aSourceFieldName, aDefaultTimezone)); } public interface CalculatedField { @@ -75,80 +76,62 @@ public class EntityAdapterDefinition { private class MirDateField implements CalculatedField { private String fieldName; + private String defaultTimezone; - public MirDateField(String aFieldName) { + public MirDateField(String aFieldName, String aDefaultTimezone) { fieldName = aFieldName; + defaultTimezone = aDefaultTimezone; } public Object getValue(EntityAdapter anEntityAdapter) { - Map result = new HashMap(); - String textValue = anEntityAdapter.getEntity().getValue(fieldName); - Calendar calendar = GregorianCalendar.getInstance(); - int year; - int month; - int day; - Date date; - - if (textValue!=null) { - try { - year = Integer.parseInt(textValue.substring(0,4)); - month = Integer.parseInt(textValue.substring(4,6)); - day = Integer.parseInt(textValue.substring(6,8)); - - calendar.set(year, month-1, day); - date = calendar.getTime(); - ; - - result.put("date", date); - result.put("formatted", new DateToMapAdapter(date)); - - } - catch (Throwable t) { - result=null; - } - } - return result; - } + Object result = null; + String textValue = anEntityAdapter.getEntity().getValue(fieldName); + Calendar calendar = GregorianCalendar.getInstance(); + int year; + int month; + int day; + Date date; + + if (textValue!=null) { + try { + year = Integer.parseInt(textValue.substring(0,4)); + month = Integer.parseInt(textValue.substring(4,6)); + day = Integer.parseInt(textValue.substring(6,8)); + + calendar.setTimeZone(TimeZone.getTimeZone(defaultTimezone)); + calendar.set(year, month-1, day); + + date = calendar.getTime(); + + result = new GeneratorFormatAdapters.DateFormatAdapter(date, defaultTimezone); + } + catch (Throwable t) { + result=null; + } + } + return result; + } } private class DBDateField implements CalculatedField { private String fieldName; + private String defaultTimezone; - public DBDateField(String aFieldName) { + public DBDateField(String aFieldName, String aDefaultTimezone) { fieldName = aFieldName; + defaultTimezone = aDefaultTimezone; } public Object getValue(EntityAdapter anEntityAdapter) { + Object result = null; + String text = anEntityAdapter.getEntity().getValue(fieldName); - Map result = new HashMap(); - String textValue = anEntityAdapter.getEntity().getValue(fieldName); - Calendar calendar = GregorianCalendar.getInstance(); - int year; - int month; - int day; - int hours; - int minutes; - - Date date; - - if (textValue!=null) { + if (text!=null) { try { - year = Integer.parseInt(textValue.substring(0,4)); - month = Integer.parseInt(textValue.substring(5,7)); - day = Integer.parseInt(textValue.substring(8,10)); - hours = Integer.parseInt(textValue.substring(11,13)); - minutes = Integer.parseInt(textValue.substring(14,16)); - - calendar.set(year, month-1, day, hours, minutes); - date = calendar.getTime(); - - result.put("date", date); - result.put("formatted", new DateToMapAdapter(date)); - result.put("raw", textValue); + result = new GeneratorFormatAdapters.DateFormatAdapter(StringUtil.convertMirInternalDateToDate(text), defaultTimezone); } catch (Throwable t) { - result=null; } } diff --git a/source/mir/misc/StringUtil.java b/source/mir/misc/StringUtil.java index bb26ae7d..3daf5005 100755 --- a/source/mir/misc/StringUtil.java +++ b/source/mir/misc/StringUtil.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mir.misc; @@ -35,13 +35,13 @@ import gnu.regexp.REException; import java.io.File; import java.text.NumberFormat; import java.util.Calendar; -import java.util.GregorianCalendar; +import java.util.*; import java.util.StringTokenizer; /** * Statische Hilfsmethoden zur Stringbehandlung * - * @version $Id: StringUtil.java,v 1.33 2003/04/21 12:42:52 idfx Exp $ + * @version $Id: StringUtil.java,v 1.33.2.1 2003/06/23 15:24:06 zapata Exp $ * @author mir-coders group * */ @@ -60,8 +60,8 @@ public final class StringUtil { re_mail = new RE("([a-zA-Z0-9_.-]+)@([a-zA-Z0-9_-]+)\\.([a-zA-Z0-9_.-]+)"); re_url = new RE("((https://)|(http://)|(ftp://)){1}([a-zA-Z0-9_-]+).([a-zA-Z0-9_.:-]+)/?([^ \t\r\n<>\\)\\]]+[^ \t\r\n.,<>\\)\\]])"); re_tags = new RE("<[^>]*>",RE.REG_ICASE); - re_tables = new RE("<[ \t\r\n/]*(table|td|tr)[ \t\r\n]*>",RE.REG_ICASE); - re_forbiddenTags = new RE("<[ \t\r\n/]*(body|head|script)[ \t\r\n]*>",RE.REG_ICASE); + re_tables = new RE("<[ \t\r\n/]*(table|td|tr)[ \t\r\n]*>",RE.REG_ICASE); + re_forbiddenTags = new RE("<[ \t\r\n/]*(body|head|script)[ \t\r\n]*>",RE.REG_ICASE); } catch (REException e){ System.err.println("FATAL: StringUtil: could not precompile REGEX: "+e.toString()); @@ -169,10 +169,10 @@ public final class StringUtil { return re_forbiddenTags.substituteAll(haystack,""); } - /** - * deleteHTMLTableTags - * this method deletes all , and
-tags - */ + /** + * deleteHTMLTableTags + * this method deletes all , and - + @@ -62,7 +62,7 @@ ${lang("content.create_date")}: diff --git a/templates/admin/producerqueue.template b/templates/admin/producerqueue.template index 5cbedd8c..aa24a48b 100755 --- a/templates/admin/producerqueue.template +++ b/templates/admin/producerqueue.template @@ -48,25 +48,26 @@
-tags + */ public static final String deleteHTMLTableTags(String haystack) { return re_tables.substituteAll(haystack,""); } @@ -195,155 +195,6 @@ public final class StringUtil { } /** - * converts string from format: yyyy-mm-dd__hh:mm:ss.d - * to dd.mm.yyyy hh:mm - */ - public static String dateToReadableDate(String date) { - StringBuffer returnDate = new StringBuffer(); - if (date!=null) { - - returnDate.append(date.substring(8,10)).append('.'); - returnDate.append(date.substring(5,7)).append('.'); - returnDate.append(date.substring(0,4)).append(' '); - returnDate.append(date.substring(11,16)); - } - return returnDate.toString(); - } - - /** - * converts string from format: yyyy-mm-dd__hh:mm:ss.d - * to yyyy - */ - public static String dateToYear (String date) { - StringBuffer returnDate = new StringBuffer(); - if (date!=null) { - - returnDate.append(date.substring(0,4)); - } - return returnDate.toString(); - } - - /** - * converts string from format: yyyy-mm-dd__hh:mm:ss.d - * to [m]m - */ - public static String dateToMonth (String date) { - StringBuffer returnDate = new StringBuffer(); - if (date!=null) { - if (!date.substring(5,6).equalsIgnoreCase("0")) returnDate.append(date.substring(5,7)); - else returnDate.append(date.substring(6,7)); - } - return returnDate.toString(); - } - - /** - * converts string from format: yyyy-mm-dd__hh:mm:ss.d - * to [d]d - */ - public static String dateToDayOfMonth (String date) { - StringBuffer returnDate = new StringBuffer(); - if (date!=null) { - if (!date.substring(8,9).equalsIgnoreCase("0")) returnDate.append(date.substring(8,10)); - else returnDate.append(date.substring(9,10)); - } - return returnDate.toString(); - } - - /** - * converts string from format: yyyy-mm-dd__hh:mm:ss.d - * to hh:mm - */ - public static String dateToTime (String date) { - StringBuffer returnDate = new StringBuffer(); - if (date!=null) { - returnDate.append(date.substring(11,16)); - } - return returnDate.toString(); - } - - /** - * Splits the provided CSV text into a list. stolen wholesale from - * from Jakarta Turbine StrinUtils.java -mh - * - * @param text The CSV list of values to split apart. - * @param separator The separator character. - * @return The list of values. - */ - public static String[] split(String text, String separator) - { - StringTokenizer st = new StringTokenizer(text, separator); - String[] values = new String[st.countTokens()]; - int pos = 0; - while (st.hasMoreTokens()) - { - values[pos++] = st.nextToken(); - } - return values; - } - - /** - * Joins the elements of the provided array into a single string - * containing a list of CSV elements. Stolen wholesale from Jakarta - * Turbine StringUtils.java. -mh - * - * @param list The list of values to join together. - * @param separator The separator character. - * @return The CSV text. - */ - public static String join(String[] list, String separator) - { - StringBuffer csv = new StringBuffer(); - for (int i = 0; i < list.length; i++) - { - if (i > 0) - { - csv.append(separator); - } - csv.append(list[i]); - } - return csv.toString(); - } - - /** - * Wandelet String in byte[] um. - * @param s - * @return byte[] des String - */ - - public static byte[] stringToBytes(String s) { - String crlf = System.getProperty("line.separator"); - if (!crlf.equals("\n")) - s = replace(s, "\n", crlf); - // byte[] buf = new byte[s.length()]; - byte[] buf = s.getBytes(); - return buf; - } - - /** - * Ersetzt in String s das pattern durch substitute - * @param s - * @param pattern - * @param substitute - * @return String mit den Ersetzungen - */ - public static String replace(String s, String pattern, String substitute) { - int i = 0, pLen = pattern.length(), sLen = substitute.length(); - StringBuffer buf = new StringBuffer(s.length()); - while (true) { - int j = s.indexOf(pattern, i); - if (j < 0) { - buf.append(s.substring(i)); - break; - } else { - buf.append(s.substring(i, j)); - buf.append(substitute); - i = j+pLen; - } - } - return buf.toString(); - } - - /** * Ersetzt in String s das Regexp pattern durch substitute * @param s * @param pattern @@ -359,28 +210,6 @@ public final class StringUtil { } } - - - - /** - * F?gt einen Separator an den Pfad an - * @param path - * @return Pfad mit Separator am Ende - */ - public static final String addSeparator (String path) { - return path.length() == 0 || path.endsWith(File.separator) ? path : path - + File.separatorChar; - } - - /** - * F?gt ein / ans ende des Strings and - * @param path - * @return Pfad mit / am Ende - */ - public static final String addSlash (String path) { - return path.length() == 0 || path.endsWith("/") ? path : path + '/'; - } - /** * L?scht / am Ende des Strings, falls vorhanden * @param path @@ -392,25 +221,6 @@ public final class StringUtil { } /** - * Checks to see if the path is absolute by looking for a leading file - * separater - * @param path - * @return - */ - public static boolean isAbsolutePath (String path) { - return path.startsWith(File.separator); - } - - /** - * L?scht Slash am Anfang des Strings - * @param path - * @return - */ - public static String removeFirstSlash (String path) { - return path.startsWith("/") ? path.substring(1) : path; - } - - /** * formatiert eine Zahl (0-99) zweistellig (z.B. 5 -> 05) * @return zwistellige Zahl */ @@ -428,80 +238,6 @@ public final class StringUtil { } /** - * Konvertiert Unix-Linefeeds in Win-Linefeeds - * @param s - * @return Konvertierter String - */ - public static String unixLineFeedsToWin(String s) { - int i = -1; - while (true) { - i = s.indexOf('\n', i+1); - if (i < 0) break; - if ((i == 0 || s.charAt(i-1) != '\r') && - (i == s.length()-1 || s.charAt(i+1) != '\r')) { - s = s.substring(0, i)+'\r'+s.substring(i); - i++; - } - } - return s; - } - - /** - * schnellere Variante der String.toLowerCase()-Routine - * - * @return String in Kleinbuchsten - */ - public static String toLowerCase(String s) { - int l = s.length(); - char[] a = new char[l]; - for (int i = 0; i < l; i++) - a[i] = Character.toLowerCase(s.charAt(i)); - return new String(a); - } - - /** - * Findet element im String-Array array - * @param array - * @param element - * @return Fundstelle als int oder -1 - */ - public static int indexOf(String[] array, String element) { - if (array != null) - for (int i = 0; i < array.length; i++) - if (array[i].equals(element)) - return i; - return -1; - } - - /** - * Testet auf Vorkommen von element in array - * @param array String-Array - * @param element - * @return true wenn element vorkommt, sonst false - */ - public static boolean contains(String[] array, String element) { - return indexOf(array, element) >= 0; - } - - /** - * Ermittelt CRC-Pr?fsumme von String s - * @param s - * @return CRC-Pr?fsumme - */ - public static int getCRC(String s) { - int h = 0; - char val[] = s.toCharArray(); - int len = val.length; - - for (int i = 0 ; i < len; i++) { - h &= 0x7fffffff; - h = (((h >> 30) | (h << 1)) ^ (val[i]+i)); - } - - return (h << 8) | (len & 0xff); - } - - /** * Liefert Default-Wert def zur?ck, wenn String s * kein Integer ist. * @@ -518,55 +254,6 @@ public final class StringUtil { } } - /** - * Liefert Defaultwert def zur?ck, wenn s nicht zu einem float geparsed werden kann. - * @param s - * @param def - * @return geparster float oder def - */ - public static float parseFloat(String s, float def) { - if (s == null) return def; - try { - return new Float(s).floatValue(); - } catch (NumberFormatException e) { - return def; - } - } - - /** - * Findet Ende eines Satzes in String text - * @param text - * @param startIndex - * @return index des Satzendes, oder -1 - */ - public static int findEndOfSentence(String text, int startIndex) { - while (true) { - int i = text.indexOf('.', startIndex); - if (i < 0) return -1; - if (i > 0 && !Character.isDigit(text.charAt(i-1)) && - (i+1 >= text.length() - || text.charAt(i+1) == ' ' - || text.charAt(i+1) == '\n' - || text.charAt(i+1) == '\t')) - return i+1; - startIndex = i+1; - } - } - - /** - * Findet Wortende in String text ab startIndex - * @param text - * @param startIndex - * @return Index des Wortendes, oder -1 - */ - public static int findEndOfWord(String text, int startIndex) { - int i = text.indexOf(' ', startIndex), - j = text.indexOf('\n', startIndex); - if (i < 0) i = text.length(); - if (j < 0) j = text.length(); - return Math.min(i, j); - } - /** * convertNewline2P ist eine regex-routine zum umwandeln von 2 oder mehr newlines (\n) @@ -713,5 +400,40 @@ public final class StringUtil { return content; } + /** + * Converts mir's horrible internal date format (yyyy-MM-dd HH:mm:ss+zz) into a java Date + * + * @param anInternalDate + * @return + */ + public static Date convertMirInternalDateToDate(String anInternalDate) { + Calendar calendar = new GregorianCalendar(); + + int year; + int month; + int day; + int hours; + int minutes; + int seconds; + int timezoneOffset; + + year = Integer.parseInt(anInternalDate.substring(0,4)); + month = Integer.parseInt(anInternalDate.substring(5,7)); + day = Integer.parseInt(anInternalDate.substring(8,10)); + hours = Integer.parseInt(anInternalDate.substring(11,13)); + minutes = Integer.parseInt(anInternalDate.substring(14,16)); + seconds = Integer.parseInt(anInternalDate.substring(17,19)); + + timezoneOffset = Integer.parseInt(anInternalDate.substring(20,22)); + if (anInternalDate.charAt(19) == '-') + timezoneOffset = -timezoneOffset; + + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.set(year, month-1, day, hours, minutes, seconds); + calendar.add(Calendar.HOUR, -timezoneOffset); + + return calendar.getTime(); + } + } diff --git a/source/mir/producer/NodedProducer.java b/source/mir/producer/NodedProducer.java index 8bf57cb9..e4f3da1e 100755 --- a/source/mir/producer/NodedProducer.java +++ b/source/mir/producer/NodedProducer.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mir.producer; @@ -47,10 +47,9 @@ public class NodedProducer implements Producer { verb = aVerb; baseValues = aBaseValues; isAborted = false; - isAborted = false; } - public void produce( LoggerWrapper aLogger ) throws ProducerFailure, ProducerExc { + public boolean produce( LoggerWrapper aLogger ) throws ProducerFailure, ProducerExc { Map valueMap; valueMap = new HashMap(); @@ -61,6 +60,7 @@ public class NodedProducer implements Producer { synchronized(this) { isFinished=true; + return !isAborted; } }; diff --git a/source/mir/producer/Producer.java b/source/mir/producer/Producer.java index 776049c7..a7ffe93e 100755 --- a/source/mir/producer/Producer.java +++ b/source/mir/producer/Producer.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mir.producer; @@ -32,6 +32,14 @@ package mir.producer; import mir.log.LoggerWrapper; public interface Producer { - public void produce( LoggerWrapper aLogger ) throws ProducerFailure, ProducerExc; + /** + * + * + * @param aLogger + * @return false if aborted,true if not + * @throws ProducerFailure + * @throws ProducerExc + */ + public boolean produce( LoggerWrapper aLogger ) throws ProducerFailure, ProducerExc; public void abort(); } diff --git a/source/mir/servlet/ServletModule.java b/source/mir/servlet/ServletModule.java index 12df8a97..4a158d9c 100755 --- a/source/mir/servlet/ServletModule.java +++ b/source/mir/servlet/ServletModule.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mir.servlet; @@ -134,7 +134,7 @@ public abstract class ServletModule { public void redirect(HttpServletResponse aResponse, String aQuery) throws ServletModuleExc, ServletModuleFailure { try { - aResponse.sendRedirect(MirPropertiesConfiguration.instance().getString("RootUri") + "/Mir?"+aQuery); + aResponse.sendRedirect(aResponse.encodeRedirectURL(MirPropertiesConfiguration.instance().getString("RootUri") + "/Mir?"+aQuery)); } catch (Throwable t) { throw new ServletModuleFailure("ServletModule.redirect: " +t.getMessage(), t); diff --git a/source/mir/storage/Database.java b/source/mir/storage/Database.java index fb7de4fb..7a3034ea 100755 --- a/source/mir/storage/Database.java +++ b/source/mir/storage/Database.java @@ -76,7 +76,7 @@ import mir.util.JDBCStringRoutines; * Treiber, Host, User und Passwort, ueber den der Zugriff auf die * Datenbank erfolgt. * - * @version $Id: Database.java,v 1.44.2.3 2003/05/26 03:29:46 zapata Exp $ + * @version $Id: Database.java,v 1.44.2.4 2003/06/23 15:24:06 zapata Exp $ * @author rk * */ @@ -117,11 +117,15 @@ public class Database implements StorageObject { private String database_url; private int defaultLimit; protected DatabaseAdaptor theAdaptor; - private SimpleDateFormat _dateFormatterOut = - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private SimpleDateFormat _dateFormatterIn = - new SimpleDateFormat("yyyy-MM-dd HH:mm"); - private Calendar _cal = new GregorianCalendar(); + TimeZone timezone; + SimpleDateFormat internalDateFormat; + SimpleDateFormat userInputDateFormat; +/* + private SimpleDateFormat _dateFormatterOut; + private SimpleDateFormat _dateFormatterIn; + _dateFormatterOut = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + _dateFormatterIn = new SimpleDateFormat("yyyy-MM-dd HH:mm"); +*/ /** * Kontruktor bekommt den Filenamen des Konfigurationsfiles ?bergeben. @@ -141,6 +145,13 @@ public class Database implements StorageObject { throw new StorageObjectFailure(e); } logger = new LoggerWrapper("Database"); + timezone = TimeZone.getTimeZone(configuration.getString("Mir.DefaultTimezone")); + internalDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + internalDateFormat.setTimeZone(timezone); + + userInputDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + userInputDateFormat.setTimeZone(timezone); + String theAdaptorName = configuration.getString("Database.Adaptor"); defaultLimit = Integer.parseInt(configuration.getString("Database.Limit")); @@ -349,14 +360,20 @@ public class Database implements StorageObject { if (!rs.wasNull()) { java.util.Date date = new java.util.Date(timestamp.getTime()); - outValue = _dateFormatterOut.format(date); - _cal.setTime(date); - - int offset = - _cal.get(Calendar.ZONE_OFFSET) + _cal.get(Calendar.DST_OFFSET); - String tzOffset = - StringUtil.zeroPaddingNumber(offset / _millisPerHour, 2, 2); - outValue = outValue + "+" + tzOffset; + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.setTimeZone(timezone); + outValue = internalDateFormat.format(date); + + int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); + String tzOffset = StringUtil.zeroPaddingNumber(Math.abs(offset) / _millisPerHour, 2, 2); + + if (offset<0) + outValue = outValue + "-"; + else + outValue = outValue + "+"; + outValue = outValue + tzOffset; } break; @@ -958,10 +975,11 @@ public class Database implements StorageObject { // TimeStamp stuff try { - java.util.Date d = _dateFormatterIn.parse(dateString); - Timestamp tStamp = new Timestamp(d.getTime()); - sql.append(",webdb_create='" + tStamp.toString() + "'"); - } catch (ParseException e) { + java.util.Date d = userInputDateFormat.parse(dateString); +// Timestamp tStamp = new Timestamp(d.getTime()); + sql.append(",webdb_create='" + JDBCStringRoutines.formatDate(d) + "'"); + } + catch (ParseException e) { throw new StorageObjectFailure(e); } } diff --git a/source/mir/util/DateToMapAdapter.java b/source/mir/util/DateToMapAdapter.java deleted file mode 100755 index 01159845..00000000 --- a/source/mir/util/DateToMapAdapter.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mir.util; - -import java.text.SimpleDateFormat; -import java.util.AbstractMap; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashSet; -import java.util.Set; - -import mir.misc.StringUtil; - -public class DateToMapAdapter extends AbstractMap { - Date date; - - public DateToMapAdapter(Date aDate) { - date = aDate; - } - - public Object get(Object aKey) { - if (aKey instanceof String) { - try { - // ML: quick fix to allow for the dc encoding now... - if (((String) aKey).equals("dc")) { - GregorianCalendar calendar = new GregorianCalendar(); - calendar.setTime(date); - return StringUtil.date2w3DateTime(calendar); - } - else - return new SimpleDateFormat((String) aKey).format(date); - } - catch (Throwable t) { - throw new RuntimeException( "Can't format date with format " + (String) aKey + ": " + t.getMessage()); - } - } - else return null; - } - - public Set entrySet() { - return new HashSet(); - } -} \ No newline at end of file diff --git a/source/mir/util/GeneratorFormatAdapters.java b/source/mir/util/GeneratorFormatAdapters.java index d51483a8..f6ffd461 100755 --- a/source/mir/util/GeneratorFormatAdapters.java +++ b/source/mir/util/GeneratorFormatAdapters.java @@ -1,8 +1,21 @@ package mir.util; -import java.util.*; -import java.text.*; -import mir.generator.*; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.AbstractMap; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; + +import mir.generator.Generator; +import mir.generator.GeneratorExc; +import mir.generator.GeneratorFailure; +import mir.misc.StringUtil; public class GeneratorFormatAdapters { public static class NumberFormatAdapter { @@ -13,22 +26,16 @@ public class GeneratorFormatAdapters { } public Generator.GeneratorFunction getFormat() { - return new NumberFormattingFunction(value); + return new NumberFormattingFunction(); } - private static class NumberFormattingFunction implements Generator.GeneratorFunction { - private Number value; - - public NumberFormattingFunction(Number aValue) { - value = aValue; - } - + private class NumberFormattingFunction implements Generator.GeneratorFunction { public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure { try { - if (aParameters.size()!=1 || !(aParameters.get(0) instanceof String) ) + if (aParameters.size() != 1 || ! (aParameters.get(0)instanceof String)) throw new GeneratorExc("NumberFormattingFunction : exactly 1 string parameter expected"); - return new DecimalFormat((String) (aParameters.get(0))).format(value); + return new DecimalFormat( (String) (aParameters.get(0))).format(value); } catch (GeneratorExc e) { throw e; @@ -40,4 +47,121 @@ public class GeneratorFormatAdapters { } } + public static class DateFormatAdapter { + private Date value; + private TimeZone defaultTimezone; + private String defaultTimezoneName; + + public DateFormatAdapter(Date aValue, String aDefaultTimezone) { + value = aValue; + defaultTimezoneName = aDefaultTimezone; + defaultTimezone = null; + } + + private TimeZone getDefaultTimezone() { + if (defaultTimezone == null) { + try { + defaultTimezone = TimeZone.getTimeZone(defaultTimezoneName); + } + catch (Throwable t) { + } + + if (defaultTimezone==null) + defaultTimezone = TimeZone.getDefault(); + } + + return defaultTimezone; + } + + public Generator.GeneratorFunction getFormat() { + return new DateFormattingFunction(); + } + + public Map getFormatted() { + return new DateToMapAdapter(); + } + + public Date getDate() { + return value; + } + + private class DateFormattingFunction implements Generator.GeneratorFunction { + public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure { + try { + if (aParameters.size() < 1 || aParameters.size() > 2 || + !(aParameters.get(0) instanceof String) || (aParameters.size()>1 && ! (aParameters.get(1) instanceof String))) + throw new GeneratorExc("DateFormattingFunction [timezone]: 1 or 2 string parameters expected"); + + SimpleDateFormat dateFormat = new SimpleDateFormat( (String) (aParameters.get(0))); + + TimeZone timezone = null; + if (aParameters.size() > 1) { + try { + timezone = TimeZone.getTimeZone( (String) aParameters.get(1)); + } + catch (Throwable t) { + + } + } + + if (timezone == null) + timezone = getDefaultTimezone(); + + dateFormat.setTimeZone(timezone); + + return dateFormat.format(value); + } + catch (GeneratorExc e) { + throw e; + } + catch (Throwable t) { + throw new GeneratorFailure("DateFormattingFunction: " + t.getMessage(), t); + } + }; + } + + /** + * + * retained for backwards compatibility + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ + + public class DateToMapAdapter extends AbstractMap { + public Object get(Object aKey) { + if (aKey instanceof String) { + try { + // ML: quick fix to allow for the dc encoding now... + if ( ( (String) aKey).equals("dc")) { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(value); + calendar.setTimeZone(defaultTimezone); + return StringUtil.date2w3DateTime(calendar); + } + else { + DateFormat dateFormat = new SimpleDateFormat( (String) aKey); + dateFormat.setTimeZone(defaultTimezone); + + return dateFormat.format(value); + } + } + catch (Throwable t) { + throw new RuntimeException("Can't format date with format " + (String) aKey + ": " + t.getMessage()); + } + } + else + return null; + } + + public Set entrySet() { + return new HashSet(); + } + } + + } } \ No newline at end of file diff --git a/source/mir/util/HTTPRequestParser.java b/source/mir/util/HTTPRequestParser.java index 951e458a..54dbea5a 100755 --- a/source/mir/util/HTTPRequestParser.java +++ b/source/mir/util/HTTPRequestParser.java @@ -18,18 +18,20 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mir.util; +import java.util.*; + import javax.servlet.http.HttpServletRequest; public class HTTPRequestParser { @@ -74,6 +76,24 @@ public class HTTPRequestParser { } } + public List getParameterList(String aName) { + try { + List result = new Vector(); + String items[] = request.getParameterValues(aName); + + if (items!=null) { + for (int i=0; iFINISHEDJOBS_LOGSIZE) - finishedJobs.remove(finishedJobs.size()-1); - } + return result; } - public void jobProcessed(Object aData) { - synchronized (jobs) { - Job job = (Job) dataToJob.get(aData); + private void cleanupJobList() { + synchronized (jobHandlers) { + Iterator i = jobHandlers.iterator(); + + Calendar tresholdCalendar = new GregorianCalendar(); + tresholdCalendar.add(Calendar.SECOND, -jobCleanupTreshold); + Date treshold = tresholdCalendar.getTime(); - if (job!=null) { - job.setProcessed(); - finishJob(job); + while (i.hasNext()) { + JobHandler jobHandler = (JobHandler) i.next(); + + synchronized (jobHandler) { + if (jobHandler.isFinished() && jobHandler.getLastChange().before(treshold)) { + jobHandlers.remove(jobHandler); + } + } } } } - public void jobAborted(Object aData) { - synchronized (jobs) { - Job job = (Job) dataToJob.get(aData); + private JobHandler acquirePendingJob() { + synchronized (jobHandlers) { + int priorityFound= 0; + JobHandler jobFound; + + jobFound = null; + Iterator i = jobHandlers.iterator(); + while (i.hasNext()) { + JobHandler job = (JobHandler) i.next(); - if (job!=null) { - job.setAborted(); - finishJob(job); + if (job.isPending() && (jobFound==null || priorityFoundtrue if terminated normally, false if aborted + */ + boolean run(); } - public List makeJobListSnapshot() { - synchronized (jobs) { - return (List) jobs.clone(); + public static class JobInfo { + private String identifier; + private Date lastChange; + private int status; + private long runningTime; + private int priority; + private String description; + + private JobInfo(String aDescription, int aStatus, Date aLastChange, String anIdentifier, long aRunningTime, int aPriority) { + description = aDescription; + lastChange = aLastChange; + status = aStatus; + identifier = anIdentifier; + priority = aPriority; + runningTime = aRunningTime; } - } - public List makeFinishedJobListSnapshot() { - synchronized (jobs) { - return (List) finishedJobs.clone(); + public String getDescription() { + return description; + } + + public int getStatus() { + return status; + } + + public int getPriority() { + return priority; + } + + public Date getLastChange() { + return lastChange; + } + + public String getIdentifier() { + return identifier; + } + + public long getRunningTime() { + return runningTime; } } - public class Job implements Cloneable { - private Object data; + public class JobHandler { + private Job job; + private String identifier; + private String description; + private Date lastChange; private long starttime; private long endtime; - private String identifier; private int status; private int priority; private boolean hasRun; - public Job(Object aData, String anIdentifier, int aStatus, int aPriority, Date aLastChange) { - data = aData; - status = aStatus; + public JobHandler(Job aJob, String anIdentifier, String aDescription, int aPriority) { + job = aJob; + description = aDescription; identifier = anIdentifier; priority = aPriority; - lastChange = aLastChange; - - hasRun = false; + status = STATUS_CREATED; } - public Job(Object aData, String anIdentifier, int aStatus, int aPriority) { - this(aData, anIdentifier, aStatus, aPriority, (new GregorianCalendar()).getTime()); + public JobHandler(Job aJob, String anIdentifier, String aDescription) { + this(aJob, anIdentifier, aDescription, PRIORITY_NORMAL); } - public Job(Object aData, String anIdentifier) { - this(aData, anIdentifier, STATUS_PENDING, PRIORITY_NORMAL); + public JobInfo getJobInfo() { + return new JobInfo(getDescription(), getStatus(), getLastChange(), getIdentifier(), getRunningTime(), priority); } - public Object getData() { - return data; - } + private void runJob() { + if (setProcessing()) { + if (job.run()) + setProcessed(); + else + setAborted(); + } + }; + + private void cancelOrAbortJob() { + synchronized (this) { + if (isPending()) + setCancelled(); + if (isProcessing()) + job.abort(); + } + }; public int getStatus() { synchronized(this) { @@ -204,46 +257,52 @@ public class JobQueue { } } - public Date getLastChange() { - return lastChange; - } - public String getIdentifier() { return identifier; } + public String getDescription() { + return description; + } + public long getRunningTime() { - long result = 0; + synchronized(this) { + long result = 0; - if (hasRun) { - if (isFinished()) - result = endtime; - else - result = System.currentTimeMillis(); + if (hasRun) { + if (isFinished()) + result = endtime; + else + result = System.currentTimeMillis(); - result = result-starttime; - } + result = result - starttime; + } - return result; + return result; + } } public int getPriority() { return priority; } - protected boolean setProcessing() { + private boolean setProcessing() { return setStatus(STATUS_PENDING, STATUS_PROCESSING); } - protected void setProcessed() { + private void setProcessed() { setStatus(STATUS_PROCESSING, STATUS_PROCESSED); } - protected void setAborted() { + private void setAborted() { setStatus(STATUS_PROCESSING, STATUS_ABORTED); } - protected boolean setCancelled() { + private void setPending() { + setStatus(STATUS_CREATED, STATUS_PENDING); + } + + private boolean setCancelled() { return setStatus(STATUS_PENDING, STATUS_CANCELLED); } @@ -271,6 +330,12 @@ public class JobQueue { return getStatus() == STATUS_PENDING; } + public Date getLastChange() { + synchronized (this) { + return lastChange; + } + } + private boolean setStatus(int anOldStatus, int aNewStatus) { synchronized(this) { if (status == anOldStatus) { @@ -291,10 +356,37 @@ public class JobQueue { } } } + } - protected Object clone() { - synchronized(this) { - return new Job(data, identifier, status, priority, lastChange); + private class JobQueueRunner implements Runnable { + private LoggerWrapper logger; + + public JobQueueRunner(LoggerWrapper aLogger) { + logger = aLogger; + } + + public void run() { + logger.debug("starting JobQueueRunner"); + + try { + while (true) { + JobHandler job = acquirePendingJob(); + if (job != null) { + logger.debug(" starting job ("+job.getIdentifier()+"): " +job.getDescription()); + job.runJob(); + logger.debug(" finished job ("+job.getIdentifier()+"): " +job.getDescription()); + } + else { + try { + Thread.sleep(1500); + } + catch (InterruptedException e) { + } + } + } + } + finally { + logger.warn("JobQueueRunner terminated"); } } } diff --git a/source/mircoders/global/ProducerEngine.java b/source/mircoders/global/ProducerEngine.java index b957ec2e..6c6f2826 100755 --- a/source/mircoders/global/ProducerEngine.java +++ b/source/mircoders/global/ProducerEngine.java @@ -40,7 +40,8 @@ import mir.log.LoggerToWriterAdapter; import mir.log.LoggerWrapper; import mir.producer.Producer; import mir.producer.ProducerFactory; -import mir.util.DateToMapAdapter; +import mir.util.*; +import mir.config.*; import mir.util.StringRoutines; import multex.Exc; import multex.Failure; @@ -48,22 +49,22 @@ import multex.Failure; public class ProducerEngine { // private Map producers; private JobQueue producerJobQueue; - private Thread queueThread; private LoggerWrapper logger; protected ProducerEngine() { - producerJobQueue = new JobQueue(); logger = new LoggerWrapper("Producer"); - - queueThread = new Thread(new ProducerJobQueueThread()); - queueThread.start(); + producerJobQueue = new JobQueue(new LoggerWrapper("Producer.Queue")); } public void addJob(String aProducerFactory, String aVerb) { - producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb)); + producerJobQueue.appendJob(new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb); } + public void cancelJobs(List aJobs) { + producerJobQueue.cancelJobs(aJobs); + }; + public void addTask(ProducerTask aTask) { addJob(aTask.getProducer(), aTask.getVerb()); } @@ -76,57 +77,61 @@ public class ProducerEngine { } } - private String convertStatus(JobQueue.Job aJob) { - if (aJob.hasBeenProcessed()) - return "processed"; - if (aJob.isProcessing()) - return "processing"; - if (aJob.isPending()) - return "pending"; - if (aJob.isCancelled()) - return "cancelled"; - if (aJob.hasBeenAborted()) - return "aborted"; - + private String convertStatus(JobQueue.JobInfo aJob) { + switch (aJob.getStatus()) { + case JobQueue.STATUS_ABORTED: + return "aborted"; + case JobQueue.STATUS_CANCELLED: + return "cancelled"; + case JobQueue.STATUS_CREATED: + return "created"; + case JobQueue.STATUS_PENDING: + return "pending"; + case JobQueue.STATUS_PROCESSED: + return "processed"; + case JobQueue.STATUS_PROCESSING: + return "processing"; + } return "unknown"; } - private Map convertJob(JobQueue.Job aJob) { - Map result = new HashMap(); - ProducerJob producerJob = (ProducerJob) aJob.getData(); - - result.put("identifier", aJob.getIdentifier()); - result.put("factory", producerJob.getFactoryName()); - result.put("verb", producerJob.getVerb()); - result.put("priority", new Integer(aJob.getPriority())); - result.put("runningtime", new Double((double) aJob.getRunningTime()/1000)); - result.put("status", convertStatus(aJob)); - result.put("lastchange", new DateToMapAdapter(aJob.getLastChange())); - - return result; - } + private Map convertJob(JobQueue.JobInfo aJob) { + try { + Map result = new HashMap(); + result.put("identifier", aJob.getIdentifier()); + result.put("description", aJob.getDescription()); + result.put("priority", new Integer(aJob.getPriority())); + result.put("runningtime", new Double( (double) aJob.getRunningTime() / 1000)); + result.put("status", convertStatus(aJob)); + result.put("lastchange", new GeneratorFormatAdapters.DateFormatAdapter(aJob.getLastChange(), MirPropertiesConfiguration.instance().getString("Mir.DefaultTimezone"))); + result.put("finished", new Boolean( + aJob.getStatus() == JobQueue.STATUS_PROCESSED || + aJob.getStatus() == JobQueue.STATUS_CANCELLED || + aJob.getStatus() == JobQueue.STATUS_ABORTED)); - private void convertJobList(List aSourceJobList, List aDestination) { - Iterator i = aSourceJobList.iterator(); - - while (i.hasNext()) - aDestination.add(convertJob((JobQueue.Job) i.next())); + return result; + } + catch (Throwable t) { + throw new RuntimeException(t.toString()); + } } - public List getQueueStatus() { + private List convertJobInfoList(List aJobInfoList) { List result = new Vector(); - List pendingJobs = new Vector(); - List finishedJobs = new Vector(); - producerJobQueue.makeJobListSnapshots(pendingJobs, finishedJobs); + Iterator i = aJobInfoList.iterator(); - convertJobList(pendingJobs, result); - convertJobList(finishedJobs, result); + while (i.hasNext()) + result.add(convertJob((JobQueue.JobInfo) i.next())); return result; } -private class ProducerJob { + public List getQueueStatus() { + return convertJobInfoList(producerJobQueue.getJobsInfo()); + } + + private class ProducerJob implements JobQueue.Job { private String factoryName; private String verb; private Producer producer; @@ -151,10 +156,11 @@ private class ProducerJob { } } - public void execute() { + public boolean run() { ProducerFactory factory; long startTime; long endTime; + boolean result = false; Map startingMap = new HashMap(); startTime = System.currentTimeMillis(); @@ -170,7 +176,7 @@ private class ProducerJob { producer = factory.makeProducer(verb, startingMap); } if (producer!=null) { - producer.produce(logger); + result = producer.produce(logger); } } } @@ -180,6 +186,8 @@ private class ProducerJob { } endTime = System.currentTimeMillis(); logger.info("Done producing job: " + factoryName + "." + verb + ", time elapsed:" + (endTime-startTime) + " ms"); + + return result; } boolean isAborted() { @@ -187,31 +195,6 @@ private class ProducerJob { } } - private class ProducerJobQueueThread implements Runnable { - public void run() { - logger.debug("starting ProducerJobQueueThread"); - - while (true) { - ProducerJob job = (ProducerJob) producerJobQueue.acquirePendingJob(); - if (job!=null) { - job.execute(); - if (job.isAborted()) - producerJobQueue.jobAborted(job); - else - producerJobQueue.jobProcessed(job); - } - else - { - try { - Thread.sleep(1500); - } - catch (InterruptedException e) { - } - } - } - } - } - public static class ProducerEngineExc extends Exc { public ProducerEngineExc(String aMessage) { super(aMessage); diff --git a/source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java b/source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java index d56ce9fb..97ef36ab 100755 --- a/source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java +++ b/source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java @@ -89,9 +89,9 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer { protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure, MirLocalizerExc { try { - anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create"); - anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange"); - anEntityAdapterDefinition.addMirDateField("date", "date"); + anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone")); + anEntityAdapterDefinition.addDBDateField("changedate", "webdb_lastchange", configuration.getString("Mir.DefaultTimezone")); + anEntityAdapterDefinition.addMirDateField("date", "date", configuration.getString("Mir.DefaultTimezone")); anEntityAdapterDefinition.addCalculatedField("to_topics", new ContentToTopicsField()); anEntityAdapterDefinition.addCalculatedField("to_comments", new ContentToCommentsField()); anEntityAdapterDefinition.addCalculatedField("language", new ContentToLanguageField()); @@ -131,7 +131,7 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer { protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure { try { - anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create"); + anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone")); anEntityAdapterDefinition.addCalculatedField("to_content", new CommentToContentField()); anEntityAdapterDefinition.addCalculatedField("status", new CommentToStatusField()); @@ -175,7 +175,7 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer { result.addMapping( "commentStatus", DatabaseCommentStatus.getInstance(), new EntityAdapterDefinition()); definition = new EntityAdapterDefinition(); - definition.addDBDateField("creationdate", "webdb_create"); + definition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone")); result.addMapping( "breakingNews", DatabaseBreaking.getInstance(), definition); result.addMapping( "imageType", DatabaseImageType.getInstance(), new EntityAdapterDefinition()); diff --git a/source/mircoders/localizer/basic/MirBasicProducerAssistantLocalizer.java b/source/mircoders/localizer/basic/MirBasicProducerAssistantLocalizer.java index 00d51314..b3ca557f 100755 --- a/source/mircoders/localizer/basic/MirBasicProducerAssistantLocalizer.java +++ b/source/mircoders/localizer/basic/MirBasicProducerAssistantLocalizer.java @@ -39,9 +39,8 @@ import mir.entity.adapter.EntityAdapter; import mir.entity.adapter.EntityIteratorAdapter; import mir.log.LoggerWrapper; import mir.misc.StringUtil; -import mir.util.DateToMapAdapter; -import mir.util.GeneratorExpressionFunctions; import mir.util.*; +import mir.util.GeneratorExpressionFunctions; import mir.util.GeneratorIntegerFunctions; import mir.util.GeneratorListFunctions; import mir.util.GeneratorStringFunctions; @@ -67,7 +66,7 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL configMap.put("openAction", MirGlobal.config().getString("Producer.OpenAction")); configMap.put("docRoot", MirGlobal.config().getString("RootUri")); configMap.put("actionRoot", MirGlobal.config().getString("RootUri") + "/servlet/Mir"); - configMap.put("now", new DateToMapAdapter( (new GregorianCalendar()).getTime())); + configMap.put("now", new GeneratorFormatAdapters.DateFormatAdapter(new GregorianCalendar().getTime(), MirGlobal.config().getString("Mir.DefaultTimezone"))); configMap.put("videoHost", MirGlobal.config().getString("Producer.Video.Host")); configMap.put("audioHost", MirGlobal.config().getString("Producer.Audio.Host")); configMap.put("imageHost", MirGlobal.config().getString("Producer.Image.Host")); diff --git a/source/mircoders/servlet/ServletHelper.java b/source/mircoders/servlet/ServletHelper.java index 389ae612..c0937ca2 100755 --- a/source/mircoders/servlet/ServletHelper.java +++ b/source/mircoders/servlet/ServletHelper.java @@ -141,7 +141,7 @@ public class ServletHelper { public static void redirect(HttpServletResponse aResponse, String aQuery) throws ServletModuleExc, ServletModuleFailure { try { - aResponse.sendRedirect(MirPropertiesConfiguration.instance().getString("RootUri") + "/Mir?"+aQuery); + aResponse.sendRedirect(aResponse.encodeRedirectURL(MirPropertiesConfiguration.instance().getString("RootUri") + "/Mir?"+aQuery)); } catch (Throwable t) { throw new ServletModuleFailure("ServletModule.redirect: " +t.getMessage(), t); diff --git a/source/mircoders/servlet/ServletModuleProducer.java b/source/mircoders/servlet/ServletModuleProducer.java index fab7cbdf..26af5336 100755 --- a/source/mircoders/servlet/ServletModuleProducer.java +++ b/source/mircoders/servlet/ServletModuleProducer.java @@ -36,20 +36,20 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Vector; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.struts.util.MessageResources; + import mir.generator.Generator; import mir.log.LoggerWrapper; import mir.producer.ProducerFactory; import mir.servlet.ServletModule; import mir.servlet.ServletModuleFailure; +import mir.util.HTTPRequestParser; import mir.util.ResourceBundleGeneratorFunction; import mircoders.global.MirGlobal; -import org.apache.struts.util.MessageResources; - public class ServletModuleProducer extends ServletModule { private static ServletModuleProducer instance = new ServletModuleProducer(); @@ -79,14 +79,15 @@ public class ServletModuleProducer extends ServletModule defaultAction="showProducerQueueStatus"; } - public void showMessage(PrintWriter aWriter, Locale aLocale, String aMessage, String anArgument1, String anArgument2) { + public void showMessage(HttpServletRequest aRequest, HttpServletResponse aResponse, String aMessage, String anArgument1, String anArgument2) { Map responseData; try { - responseData = new HashMap(); + responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)}); responseData.put("message", aMessage); responseData.put("argument1", anArgument1); responseData.put("argument2", anArgument2); - generateResponse("infomessage.template", aWriter, responseData, aLocale); + + ServletHelper.generateResponse(aResponse.getWriter(), responseData, "infomessage.template"); } catch (Throwable t) { throw new ServletModuleFailure(t); @@ -139,7 +140,7 @@ public class ServletModuleProducer extends ServletModule } } - public void produce(HttpServletRequest req, HttpServletResponse res) { + public void produce(HttpServletRequest aRequest, HttpServletResponse aResponse) { /* * This method will only be called by external scripts (e.g. from cron jobs). * The output therefore is very simple. @@ -147,11 +148,11 @@ public class ServletModuleProducer extends ServletModule */ try { - PrintWriter out = res.getWriter(); + PrintWriter out = aResponse.getWriter(); - if (req.getParameter("producer")!=null) { - String producerParam = req.getParameter("producer"); - String verbParam = req.getParameter("verb"); + if (aRequest.getParameter("producer")!=null) { + String producerParam = aRequest.getParameter("producer"); + String verbParam = aRequest.getParameter("verb"); MirGlobal.producerEngine().addJob(producerParam, verbParam); out.println("job added"); @@ -165,7 +166,7 @@ public class ServletModuleProducer extends ServletModule public void produceAllNew(HttpServletRequest aRequest, HttpServletResponse aResponse) { try { MirGlobal.localizer().producers().produceAllNew(); - showMessage(aResponse.getWriter(), getLocale(aRequest), "produceAllNewAddedToQueue", "", ""); + showMessage(aRequest, aResponse, "produceAllNewAddedToQueue", "", ""); } catch (Throwable t) { throw new ServletModuleFailure(t); @@ -188,7 +189,16 @@ public class ServletModuleProducer extends ServletModule } } - public void cancelAbortJob(HttpServletRequest aRequest, HttpServletResponse aResponse) { - // ML: to be coded + public void cancel(HttpServletRequest aRequest, HttpServletResponse aResponse) { + try { + HTTPRequestParser requestParser = new HTTPRequestParser(aRequest); + List jobs = new Vector(requestParser.getParameterList("jobid")); + + MirGlobal.producerEngine().cancelJobs(jobs); + ServletHelper.redirect(aResponse, "Producer", "showProducerQueueStatus"); + } + catch (Throwable t) { + throw new ServletModuleFailure(t); + } } } diff --git a/templates/admin/abuse.log.template b/templates/admin/abuse.log.template index b6b201ce..f80a9395 100755 --- a/templates/admin/abuse.log.template +++ b/templates/admin/abuse.log.template @@ -23,7 +23,7 @@
${l.timestamp["yyyy-MM-dd HH:mm"]}${l.timestamp.format("yyyy-MM-dd HH:mm")} ${l.ip} diff --git a/templates/admin/content.template b/templates/admin/content.template index fb51eaca..506440b6 100755 --- a/templates/admin/content.template +++ b/templates/admin/content.template @@ -53,7 +53,7 @@ ${lang("content.lastchange_date")}: - ${utility.encodeHTML(article.webdb_lastchange)}
+ ${utility.encodeHTML(article.changedate.format("yyyy-MM-dd HH:mm"))}
- ${utility.encodeHTML(article.webdb_create)}
${lang("edit")}: + ${utility.encodeHTML(article.creationdate.format("yyyy-MM-dd HH:mm"))}
${lang("edit")}:   (yyyy-mm-dd [HH:mm])
-

${lang("producer.jobqueue.title")}

+

${lang("producer.jobqueue.title")} ${lang("producer.jobqueue.refresh")}

+
+ + + - - - - - - - + + + + + class="listrow1"class="listrow2"> - - + @@ -74,11 +75,15 @@ - + - ML: needs to be implemented - - + @@ -88,12 +93,13 @@ -
${lang("producer.job.name")}${lang("producer.job.status")}${lang("producer.job.date")}${lang("producer.job.runningtime")} ${lang("producer.job.name")}${lang("producer.job.status")}${lang("producer.job.date")}${lang("producer.job.runningtime")} 
${q.factory}(${q.verb})${q.description} ${q.status}${q.status} ${q.lastchange["HH:mm:ss"]}${q.lastchange.format("HH:mm:ss")} ${q.runningtime.format("####.#")}s${lang("producer.job.cancel")} + + + +   + +
+
- ${lang("producer.jobqueue.refresh")} +
+
diff --git a/web/style/admin.css b/web/style/admin.css index 21c49a7e..11908ba3 100755 --- a/web/style/admin.css +++ b/web/style/admin.css @@ -182,3 +182,15 @@ a:hover { .lynx { display:none; } +.majorbutton { +} + +.minorbutton { + background-color:#DDDDDD; + color: #990000; + font-size:1em; + padding:2px; + padding-left:8px; + padding-right:8px; +// border:1px solid #990000; +} -- 2.11.0