No functional change, assures that all Java files are svn:native
This is mostly related with the new pricat component and 2 files in cmssite (I
guess also related with the new pricat component )
git-svn-id: https://svn.apache.org/repos/asf/ofbiz/trunk@1774165 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractHtmlReport.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractHtmlReport.java
index f5a7b5e..fddd936 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractHtmlReport.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractHtmlReport.java
@@ -1,140 +1,140 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.jsp.JspException;
-
-import org.apache.ofbiz.htmlreport.util.ReportStringUtil;
-
-/**
- * HTML report output to be used for database create tables / drop tables operations.
- *
- */
-public abstract class AbstractHtmlReport extends HtmlReport {
-
- public static final String module = AbstractHtmlReport.class.getName();
-
- public final static String THREAD_TYPE = "thread_type";
-
- public final static String RUN_CREATETABLE_SCRIPT = "runcreatetablescript";
-
- public final static String RUN_DROPTABLE_SCRIPT = "rundroptablescript";
-
- public final static String FILE_REPORT_OUTPUT = "specialpurpose/pricat/webapp/pricat/ftl/report.ftl";
-
- /**
- * Constructs a new report using the provided locale for the output language.
- *
- * @param request HttpServletRequest
- * @param response HttpServletResponse
- */
- public AbstractHtmlReport(HttpServletRequest request, HttpServletResponse response) {
- this(request, response, false, false);
- }
-
- /**
- * Constructs a new report using the provided locale for the output language.
- *
- * @param request HttpServletRequest
- * @param response HttpServletResponse
- * @param writeHtml if <code>true</code>, this report should generate HTML instead of JavaScript output
- * @param isTransient If set to <code>true</code> nothing is kept in memory
- */
- public AbstractHtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
- super(request, response, writeHtml, isTransient);
- }
-
- /**
- * Prepare display an html report.
- *
- * @throws IOException
- */
- public void prepareDisplayReport(HttpServletRequest request, HttpServletResponse response, String name, String dialogUri) throws IOException {
-
- if (ReportStringUtil.isNotEmpty(dialogUri)) {
- setDialogRealUri(request, dialogUri);
- }
-
- String action = getParamAction(request);
- if (action == null) action = "";
- if (action.equals("reportend") || action.equals("cancel")) {
- setParamAction("reportend");
- } else if (action.equals("reportupdate")) {
- setParamAction("reportupdate");
- } else {
- InterfaceReportThread thread = initializeThread(request, response, name);
- thread.start();
- setParamAction("reportbegin");
- setParamThread(thread.getUUID().toString());
- }
- }
-
- /**
- * Initializes the report thread to use for this report.<p>
- *
- * @return the reported thread to use for this report.
- */
- public abstract InterfaceReportThread initializeThread(HttpServletRequest request, HttpServletResponse response, String name);
-
- /**
- * Set the report dialog uri.
- *
- * @param dialogUri
- */
- public void setDialogRealUri(HttpServletRequest request, String dialogUri) {
- request.setAttribute(DIALOG_URI, dialogUri);
- }
-
- public static String checkButton(HttpServletRequest request, HttpServletResponse response) {
- String action = request.getParameter("action");
- if (ReportStringUtil.isNotEmpty(action)) {
- if (action.equalsIgnoreCase("ok")) {
- request.removeAttribute(SESSION_REPORT_CLASS);
- request.removeAttribute(DIALOG_URI);
- return "ok";
- } else if (action.equalsIgnoreCase("cancel")) {
- request.removeAttribute(SESSION_REPORT_CLASS);
- request.removeAttribute(DIALOG_URI);
- return "cancel";
- }
- }
- action = request.getParameter("ok");
- if (ReportStringUtil.isNotEmpty(action)) {
- if (action.equalsIgnoreCase("ok")) {
- request.removeAttribute(SESSION_REPORT_CLASS);
- request.removeAttribute(DIALOG_URI);
- return "ok";
- }
- }
- action = request.getParameter("cancel");
- if (ReportStringUtil.isNotEmpty(action)) {
- if (action.equalsIgnoreCase("cancel")) {
- request.removeAttribute(SESSION_REPORT_CLASS);
- request.removeAttribute(DIALOG_URI);
- return "cancel";
- }
- }
-
- return "success";
- }
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+
+import org.apache.ofbiz.htmlreport.util.ReportStringUtil;
+
+/**
+ * HTML report output to be used for database create tables / drop tables operations.
+ *
+ */
+public abstract class AbstractHtmlReport extends HtmlReport {
+
+ public static final String module = AbstractHtmlReport.class.getName();
+
+ public final static String THREAD_TYPE = "thread_type";
+
+ public final static String RUN_CREATETABLE_SCRIPT = "runcreatetablescript";
+
+ public final static String RUN_DROPTABLE_SCRIPT = "rundroptablescript";
+
+ public final static String FILE_REPORT_OUTPUT = "specialpurpose/pricat/webapp/pricat/ftl/report.ftl";
+
+ /**
+ * Constructs a new report using the provided locale for the output language.
+ *
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ */
+ public AbstractHtmlReport(HttpServletRequest request, HttpServletResponse response) {
+ this(request, response, false, false);
+ }
+
+ /**
+ * Constructs a new report using the provided locale for the output language.
+ *
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @param writeHtml if <code>true</code>, this report should generate HTML instead of JavaScript output
+ * @param isTransient If set to <code>true</code> nothing is kept in memory
+ */
+ public AbstractHtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
+ super(request, response, writeHtml, isTransient);
+ }
+
+ /**
+ * Prepare display an html report.
+ *
+ * @throws IOException
+ */
+ public void prepareDisplayReport(HttpServletRequest request, HttpServletResponse response, String name, String dialogUri) throws IOException {
+
+ if (ReportStringUtil.isNotEmpty(dialogUri)) {
+ setDialogRealUri(request, dialogUri);
+ }
+
+ String action = getParamAction(request);
+ if (action == null) action = "";
+ if (action.equals("reportend") || action.equals("cancel")) {
+ setParamAction("reportend");
+ } else if (action.equals("reportupdate")) {
+ setParamAction("reportupdate");
+ } else {
+ InterfaceReportThread thread = initializeThread(request, response, name);
+ thread.start();
+ setParamAction("reportbegin");
+ setParamThread(thread.getUUID().toString());
+ }
+ }
+
+ /**
+ * Initializes the report thread to use for this report.<p>
+ *
+ * @return the reported thread to use for this report.
+ */
+ public abstract InterfaceReportThread initializeThread(HttpServletRequest request, HttpServletResponse response, String name);
+
+ /**
+ * Set the report dialog uri.
+ *
+ * @param dialogUri
+ */
+ public void setDialogRealUri(HttpServletRequest request, String dialogUri) {
+ request.setAttribute(DIALOG_URI, dialogUri);
+ }
+
+ public static String checkButton(HttpServletRequest request, HttpServletResponse response) {
+ String action = request.getParameter("action");
+ if (ReportStringUtil.isNotEmpty(action)) {
+ if (action.equalsIgnoreCase("ok")) {
+ request.removeAttribute(SESSION_REPORT_CLASS);
+ request.removeAttribute(DIALOG_URI);
+ return "ok";
+ } else if (action.equalsIgnoreCase("cancel")) {
+ request.removeAttribute(SESSION_REPORT_CLASS);
+ request.removeAttribute(DIALOG_URI);
+ return "cancel";
+ }
+ }
+ action = request.getParameter("ok");
+ if (ReportStringUtil.isNotEmpty(action)) {
+ if (action.equalsIgnoreCase("ok")) {
+ request.removeAttribute(SESSION_REPORT_CLASS);
+ request.removeAttribute(DIALOG_URI);
+ return "ok";
+ }
+ }
+ action = request.getParameter("cancel");
+ if (ReportStringUtil.isNotEmpty(action)) {
+ if (action.equalsIgnoreCase("cancel")) {
+ request.removeAttribute(SESSION_REPORT_CLASS);
+ request.removeAttribute(DIALOG_URI);
+ return "cancel";
+ }
+ }
+
+ return "success";
+ }
}
\ No newline at end of file
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReport.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReport.java
index b565b8b..bd01ccf 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReport.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReport.java
@@ -1,187 +1,187 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Base report class.
- *
- */
-public abstract class AbstractReport implements InterfaceReport {
-
- /** Contains all error messages generated by the report. */
- private List<Object> errors;
-
- /** The locale this report is written in. */
- private Locale locale;
-
- /** Runtime of the report. */
- private long startTime;
-
- /** Contains all warning messages generated by the report. */
- private List<Object> warnings = new ArrayList<Object>();
-
- /** Day constant. */
- private static final long DAYS = 1000 * 60 * 60 * 24;
-
- /** Hour constant. */
- private static final long HOURS = 1000 * 60 * 60;
-
- /** Minute constant. */
- private static final long MINUTES = 1000 * 60;
-
- /** Second constant. */
- private static final long SECONDS = 1000;
-
- public static final String SESSION_REPORT_CLASS = "OFBIZ_HTML_REPORT";
-
- public void addError(Object obj) {
-
- errors.add(obj);
- }
-
- public void addWarning(Object obj) {
-
- warnings.add(obj);
- }
-
- public String formatRuntime() {
-
- long runtime = getRuntime();
- long seconds = (runtime / SECONDS) % 60;
- long minutes = (runtime / MINUTES) % 60;
- long hours = (runtime / HOURS) % 24;
- long days = runtime / DAYS;
- StringBuffer strBuf = new StringBuffer();
-
- if (days > 0) {
- if (days < 10) {
- strBuf.append('0');
- }
- strBuf.append(days);
- strBuf.append(':');
- }
-
- if (hours < 10) {
- strBuf.append('0');
- }
- strBuf.append(hours);
- strBuf.append(':');
-
- if (minutes < 10) {
- strBuf.append('0');
- }
- strBuf.append(minutes);
- strBuf.append(':');
-
- if (seconds < 10) {
- strBuf.append('0');
- }
- strBuf.append(seconds);
-
- return strBuf.toString();
- }
-
- public List<Object> getErrors() {
- return errors;
- }
-
- public Locale getLocale() {
- return locale;
- }
-
- public long getRuntime() {
- return System.currentTimeMillis() - startTime;
- }
-
- public List<Object> getWarnings() {
- return warnings;
- }
-
- public boolean hasError() {
- return (errors.size() > 0);
- }
-
- public boolean hasWarning() {
- return (warnings.size() > 0);
- }
-
- public void resetRuntime() {
- startTime = System.currentTimeMillis();
- }
-
- /**
- * Initializes some member variables for this report.<p>
- *
- * @param locale the locale for this report
- */
- protected void init(Locale locale) {
- startTime = System.currentTimeMillis();
- this.locale = locale;
- errors = new ArrayList<Object>();
- }
-
- /**
- * Prints a String to the report.<p>
- *
- * @param value the String to add
- */
- public void print(String value) {
- print(value, FORMAT_DEFAULT);
- }
-
- /**
- * Prints a String to the report, using the indicated formatting.<p>
- *
- * Use the contants starting with <code>FORMAT</code> from this interface
- * to indicate which formatting to use.<p>
- *
- * @param value the message container to add
- * @param format the formatting to use for the output
- */
- public abstract void print(String value, int format);
-
- /**
- * Prints a String with line break to the report.<p>
- *
- * @param value the message container to add
- */
- public void println(String value) {
-
- println(value, FORMAT_DEFAULT);
- }
-
- /**
- * Prints a String with line break to the report, using the indicated formatting.<p>
- *
- * Use the contants starting with <code>FORMAT</code> from this interface
- * to indicate which formatting to use.<p>
- *
- * @param value the String to add
- * @param format the formatting to use for the output
- */
- public void println(String value, int format) {
- print(value, format);
- println();
- }
-
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Base report class.
+ *
+ */
+public abstract class AbstractReport implements InterfaceReport {
+
+ /** Contains all error messages generated by the report. */
+ private List<Object> errors;
+
+ /** The locale this report is written in. */
+ private Locale locale;
+
+ /** Runtime of the report. */
+ private long startTime;
+
+ /** Contains all warning messages generated by the report. */
+ private List<Object> warnings = new ArrayList<Object>();
+
+ /** Day constant. */
+ private static final long DAYS = 1000 * 60 * 60 * 24;
+
+ /** Hour constant. */
+ private static final long HOURS = 1000 * 60 * 60;
+
+ /** Minute constant. */
+ private static final long MINUTES = 1000 * 60;
+
+ /** Second constant. */
+ private static final long SECONDS = 1000;
+
+ public static final String SESSION_REPORT_CLASS = "OFBIZ_HTML_REPORT";
+
+ public void addError(Object obj) {
+
+ errors.add(obj);
+ }
+
+ public void addWarning(Object obj) {
+
+ warnings.add(obj);
+ }
+
+ public String formatRuntime() {
+
+ long runtime = getRuntime();
+ long seconds = (runtime / SECONDS) % 60;
+ long minutes = (runtime / MINUTES) % 60;
+ long hours = (runtime / HOURS) % 24;
+ long days = runtime / DAYS;
+ StringBuffer strBuf = new StringBuffer();
+
+ if (days > 0) {
+ if (days < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(days);
+ strBuf.append(':');
+ }
+
+ if (hours < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(hours);
+ strBuf.append(':');
+
+ if (minutes < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(minutes);
+ strBuf.append(':');
+
+ if (seconds < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(seconds);
+
+ return strBuf.toString();
+ }
+
+ public List<Object> getErrors() {
+ return errors;
+ }
+
+ public Locale getLocale() {
+ return locale;
+ }
+
+ public long getRuntime() {
+ return System.currentTimeMillis() - startTime;
+ }
+
+ public List<Object> getWarnings() {
+ return warnings;
+ }
+
+ public boolean hasError() {
+ return (errors.size() > 0);
+ }
+
+ public boolean hasWarning() {
+ return (warnings.size() > 0);
+ }
+
+ public void resetRuntime() {
+ startTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Initializes some member variables for this report.<p>
+ *
+ * @param locale the locale for this report
+ */
+ protected void init(Locale locale) {
+ startTime = System.currentTimeMillis();
+ this.locale = locale;
+ errors = new ArrayList<Object>();
+ }
+
+ /**
+ * Prints a String to the report.<p>
+ *
+ * @param value the String to add
+ */
+ public void print(String value) {
+ print(value, FORMAT_DEFAULT);
+ }
+
+ /**
+ * Prints a String to the report, using the indicated formatting.<p>
+ *
+ * Use the contants starting with <code>FORMAT</code> from this interface
+ * to indicate which formatting to use.<p>
+ *
+ * @param value the message container to add
+ * @param format the formatting to use for the output
+ */
+ public abstract void print(String value, int format);
+
+ /**
+ * Prints a String with line break to the report.<p>
+ *
+ * @param value the message container to add
+ */
+ public void println(String value) {
+
+ println(value, FORMAT_DEFAULT);
+ }
+
+ /**
+ * Prints a String with line break to the report, using the indicated formatting.<p>
+ *
+ * Use the contants starting with <code>FORMAT</code> from this interface
+ * to indicate which formatting to use.<p>
+ *
+ * @param value the String to add
+ * @param format the formatting to use for the output
+ */
+ public void println(String value, int format) {
+ print(value, format);
+ println();
+ }
+
}
\ No newline at end of file
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReportThread.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReportThread.java
index 2e86a40..9b2c956 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReportThread.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/AbstractReportThread.java
@@ -1,213 +1,213 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport;
-
-import java.util.List;
-import java.util.Locale;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.ofbiz.base.util.UtilHttp;
-import org.safehaus.uuid.EthernetAddress;
-import org.safehaus.uuid.UUID;
-import org.safehaus.uuid.UUIDGenerator;
-
-/**
- * Provides a common Thread class for the reports.
- *
- */
-public abstract class AbstractReportThread extends Thread implements InterfaceReportThread {
-
- /** Indicates if the thread was already checked by the grim reaper. */
- private boolean doomed;
-
- /** The report that belongs to the thread. */
- private InterfaceReport report;
-
- /** The time this report is running. */
- private long startTime;
-
- private UUID uuid;
-
- private Locale locale;
-
- /**
- * Constructs a new report Thread with the given name.
- */
- protected AbstractReportThread(HttpServletRequest request, HttpServletResponse response, String name) {
-
- super(Thread.currentThread().getThreadGroup(), name);
- // report Threads are never daemon Threads
- setDaemon(false);
- // the session must not be updated when it is used in a report
- EthernetAddress ethernetAddress = UUIDGenerator.getInstance().getDummyAddress();
- uuid = UUIDGenerator.getInstance().generateTimeBasedUUID(ethernetAddress);
-
- setName(name + " [" + uuid.toString() + "]");
- // new Threads are not doomed
- doomed = false;
- // set start time
- startTime = System.currentTimeMillis();
- locale = UtilHttp.getLocale(request);
- }
-
-
- public UUID getUUID() {
- return uuid;
- }
-
- /**
- * Adds an error object to the list of errors that occured during the report.
- *
- * @param obj the error object
- */
- public void addError(Object obj) {
-
- if (getReport() != null) {
- getReport().addError(obj);
- }
- }
-
- /**
- * Returns the error exception in case there was an error during the execution of
- * this Thread, null otherwise.
- *
- * @return the error exception in case there was an error, null otherwise
- */
- public Throwable getError() {
-
- return null;
- }
-
- /**
- * Returns a list of all errors that occured during the report.
- *
- * @return an error list that occured during the report
- */
- public List<?> getErrors() {
-
- if (getReport() != null) {
- return getReport().getErrors();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the part of the report that is ready for output.
- *
- * @return the part of the report that is ready for output
- */
- public abstract String getReportUpdate();
-
- /**
- * Returns the time this report has been running.
- *
- * @return the time this report has been running
- */
- public synchronized long getRuntime() {
-
- if (doomed) {
- return startTime;
- } else {
- return System.currentTimeMillis() - startTime;
- }
- }
-
- /**
- * Returns if the report generated an error output.
- *
- * @return true if the report generated an error, otherwise false
- */
- public boolean hasError() {
-
- if (getReport() != null) {
- return (getReport().getErrors().size() > 0);
- } else {
- return false;
- }
- }
-
- /**
- * Returns true if this thread is already "doomed" to be deleted.
- *
- * A OFBiz deamon Thread (the "Grim Reaper") will collect all
- * doomed Threads, i.e. threads that are not longer active for some
- * time.
- *
- * @return true if this thread is already "doomed" to be deleted
- */
- public synchronized boolean isDoomed() {
-
- if (isAlive()) {
- // as long as the Thread is still active it is never doomed
- return false;
- }
- if (doomed) {
- // not longer active, and already doomed, so rest in peace...
- return true;
- }
- // condemn the Thread to be collected by the grim reaper next time
- startTime = getRuntime();
- doomed = true;
- return false;
- }
-
- /**
- * Returns the report where the output of this Thread is written to.
- *
- * @return the report where the output of this Thread is written to
- */
- protected InterfaceReport getReport() {
-
- return report;
- }
-
- /**
- * Initialize a HTML report for this Thread.
- *
- */
- protected void initHtmlReport(HttpServletRequest request, HttpServletResponse response) {
-
- report = HtmlReport.getInstance(request, response);
- ((HtmlReport) report).setParamThread(getUUID().toString());
- }
-
- /**
- * Initialize a HTML report for this Thread.
- *
- */
- protected void initHtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
-
- report = HtmlReport.getInstance(request, response, writeHtml, isTransient);
- ((HtmlReport) report).setParamThread(getUUID().toString());
- }
-
- protected void initHtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient, String logFileName) {
-
- report = HtmlReport.getInstance(request, response, writeHtml, isTransient, logFileName);
- ((HtmlReport) report).setParamThread(getUUID().toString());
- }
-
- protected Locale getLocale() {
- return locale;
- }
-
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport;
+
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.ofbiz.base.util.UtilHttp;
+import org.safehaus.uuid.EthernetAddress;
+import org.safehaus.uuid.UUID;
+import org.safehaus.uuid.UUIDGenerator;
+
+/**
+ * Provides a common Thread class for the reports.
+ *
+ */
+public abstract class AbstractReportThread extends Thread implements InterfaceReportThread {
+
+ /** Indicates if the thread was already checked by the grim reaper. */
+ private boolean doomed;
+
+ /** The report that belongs to the thread. */
+ private InterfaceReport report;
+
+ /** The time this report is running. */
+ private long startTime;
+
+ private UUID uuid;
+
+ private Locale locale;
+
+ /**
+ * Constructs a new report Thread with the given name.
+ */
+ protected AbstractReportThread(HttpServletRequest request, HttpServletResponse response, String name) {
+
+ super(Thread.currentThread().getThreadGroup(), name);
+ // report Threads are never daemon Threads
+ setDaemon(false);
+ // the session must not be updated when it is used in a report
+ EthernetAddress ethernetAddress = UUIDGenerator.getInstance().getDummyAddress();
+ uuid = UUIDGenerator.getInstance().generateTimeBasedUUID(ethernetAddress);
+
+ setName(name + " [" + uuid.toString() + "]");
+ // new Threads are not doomed
+ doomed = false;
+ // set start time
+ startTime = System.currentTimeMillis();
+ locale = UtilHttp.getLocale(request);
+ }
+
+
+ public UUID getUUID() {
+ return uuid;
+ }
+
+ /**
+ * Adds an error object to the list of errors that occured during the report.
+ *
+ * @param obj the error object
+ */
+ public void addError(Object obj) {
+
+ if (getReport() != null) {
+ getReport().addError(obj);
+ }
+ }
+
+ /**
+ * Returns the error exception in case there was an error during the execution of
+ * this Thread, null otherwise.
+ *
+ * @return the error exception in case there was an error, null otherwise
+ */
+ public Throwable getError() {
+
+ return null;
+ }
+
+ /**
+ * Returns a list of all errors that occured during the report.
+ *
+ * @return an error list that occured during the report
+ */
+ public List<?> getErrors() {
+
+ if (getReport() != null) {
+ return getReport().getErrors();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the part of the report that is ready for output.
+ *
+ * @return the part of the report that is ready for output
+ */
+ public abstract String getReportUpdate();
+
+ /**
+ * Returns the time this report has been running.
+ *
+ * @return the time this report has been running
+ */
+ public synchronized long getRuntime() {
+
+ if (doomed) {
+ return startTime;
+ } else {
+ return System.currentTimeMillis() - startTime;
+ }
+ }
+
+ /**
+ * Returns if the report generated an error output.
+ *
+ * @return true if the report generated an error, otherwise false
+ */
+ public boolean hasError() {
+
+ if (getReport() != null) {
+ return (getReport().getErrors().size() > 0);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if this thread is already "doomed" to be deleted.
+ *
+ * A OFBiz deamon Thread (the "Grim Reaper") will collect all
+ * doomed Threads, i.e. threads that are not longer active for some
+ * time.
+ *
+ * @return true if this thread is already "doomed" to be deleted
+ */
+ public synchronized boolean isDoomed() {
+
+ if (isAlive()) {
+ // as long as the Thread is still active it is never doomed
+ return false;
+ }
+ if (doomed) {
+ // not longer active, and already doomed, so rest in peace...
+ return true;
+ }
+ // condemn the Thread to be collected by the grim reaper next time
+ startTime = getRuntime();
+ doomed = true;
+ return false;
+ }
+
+ /**
+ * Returns the report where the output of this Thread is written to.
+ *
+ * @return the report where the output of this Thread is written to
+ */
+ protected InterfaceReport getReport() {
+
+ return report;
+ }
+
+ /**
+ * Initialize a HTML report for this Thread.
+ *
+ */
+ protected void initHtmlReport(HttpServletRequest request, HttpServletResponse response) {
+
+ report = HtmlReport.getInstance(request, response);
+ ((HtmlReport) report).setParamThread(getUUID().toString());
+ }
+
+ /**
+ * Initialize a HTML report for this Thread.
+ *
+ */
+ protected void initHtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
+
+ report = HtmlReport.getInstance(request, response, writeHtml, isTransient);
+ ((HtmlReport) report).setParamThread(getUUID().toString());
+ }
+
+ protected void initHtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient, String logFileName) {
+
+ report = HtmlReport.getInstance(request, response, writeHtml, isTransient, logFileName);
+ ((HtmlReport) report).setParamThread(getUUID().toString());
+ }
+
+ protected Locale getLocale() {
+ return locale;
+ }
+
+}
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/HtmlReport.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/HtmlReport.java
index 95b161d..761e8f6 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/HtmlReport.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/HtmlReport.java
@@ -1,1347 +1,1347 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.ofbiz.base.util.Debug;
-import org.apache.ofbiz.base.util.FileUtil;
-import org.apache.ofbiz.base.util.StringUtil;
-import org.apache.ofbiz.base.util.UtilHttp;
-import org.apache.ofbiz.base.util.UtilProperties;
-import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.htmlreport.util.ReportEncoder;
-import org.apache.ofbiz.htmlreport.util.ReportStringUtil;
-
-/**
- * HTML report output to be used in report.ftl.<p>
- *
- */
-public class HtmlReport extends AbstractReport {
-
- public static final String module = HtmlReport.class.getName();
-
- /** The delimiter that is used in the resource list request parameter. */
- public static final String DELIMITER_RESOURCES = "|";
-
- /** Request parameter name for the resource list. */
- public static final String PARAM_RESOURCELIST = "resourcelist";
-
- /** Constant for a HTML linebreak with added "real" line break. */
- protected static final String LINEBREAK = "<br>";
-
- /**
- * Constant for a HTML linebreak with added "real" line break-
- * traditional style for report threads that still use XML templates for their output.
- */
- protected static final String LINEBREAK_TRADITIONAL = "<br>\n";
-
- /** The list of report objects e.g. String, Exception ... */
- protected List<Serializable> content;
-
- /** The list of report objects e.g. String, Exception ... */
- protected List<Serializable> logContent;
-
- /**
- * Counter to remember what is already shown,
- * indicates the next index of the content list that has to be reported.
- */
- protected int indexNext;
-
- /** Flag to indicate if an exception should be displayed long or short. */
- protected boolean showExceptionStackTrace;
-
- /** If set to <code>true</code> nothing is kept in memory. */
- protected boolean isTransient;
-
- /** Boolean flag indicating whether this report should generate HTML or JavaScript output. */
- protected boolean writeHtml;
-
- /** Helper variable to deliver the html end part. */
- public static final int HTML_END = 1;
-
- /** Helper variable to deliver the html start part. */
- public static final int HTML_START = 0;
-
- /** The thread to display in this report. */
- protected String paramThread;
-
- /** The next thread to display after this report. */
- protected String paramThreadHasNext;
-
- protected String paramAction;
-
- protected String paramTitle;
-
- protected String paramResource;
-
- /** Flag for refreching workplace .*/
- protected String paramRefreshWorkplace;
-
- /** Constant for the "OK" button in the build button methods. */
- public static final int BUTTON_OK = 0;
-
- /** Constant for the "Cancel" button in the build button methods. */
- public static final int BUTTON_CANCEL = 1;
-
- /** Constant for the "Close" button in the build button methods. */
- public static final int BUTTON_CLOSE = 2;
-
- /** Constant for the "Advanced" button in the build button methods. */
- public static final int BUTTON_ADVANCED = 3;
-
- /** Constant for the "Set" button in the build button methods. */
- public static final int BUTTON_SET = 4;
-
- /** Constant for the "Details" button in the build button methods. */
- public static final int BUTTON_DETAILS = 5;
-
- /** Constant for the "OK" button in the build button methods (without form submission). */
- public static final int BUTTON_OK_NO_SUBMIT = 6;
-
- /** Constant for the "Edit" button in the build button methods (same function as "Ok" button but different text on button. */
- public static final int BUTTON_EDIT = 7;
-
- /** Constant for the "Discard" button in the build button methods (same function as "Cancel" button but different text on button. */
- public static final int BUTTON_DISCARD = 8;
-
- /** Constant for the "Back" button in the build button methods. */
- public static final int BUTTON_BACK = 9;
-
- /** Constant for the "Continue" button in the build button methods. */
- public static final int BUTTON_CONTINUE = 10;
-
- /** Constant for the "Download" button in the build button methods. */
- public static final int BUTTON_DOWNLOAD = 11;
-
- /** Request parameter value for the action: back. */
- public static final String DIALOG_BACK = "back";
-
- /** Request parameter value for the action: cancel. */
- public static final String DIALOG_CANCEL = "cancel";
-
- /** Request parameter value for the action: continue. */
- public static final String DIALOG_CONTINUE = "continue";
-
- /** Request parameter value for the action: set. */
- public static final String DIALOG_SET = "set";
-
- /** The resource list parameter value. */
- protected String paramResourcelist;
-
- /** The list of resource names for the multi operation. */
- protected List<String> resourceList;
-
- /** The key name which contains the localized message for the continue checkbox. */
- protected String paramReportContinueKey;
-
- public static final String DIALOG_URI = "dialoguri";
-
- public static final String FORM_URI = "formuri";
-
- public static final String resource = "PricatUiLabels";
-
- /** Log file. */
- protected File logFile;
-
- /** Log file name. */
- protected String logFileName;
-
- /** Log file output stream. */
- protected FileOutputStream logFileOutputStream;
-
- protected long sequenceNum = -1;
-
- /**
- * Constructs a new report using the provided locale for the output language.<p>
- *
- * @param request HttpServletRequest
- * @param response HttpServletResponse
- */
- public HtmlReport(HttpServletRequest request, HttpServletResponse response) {
-
- this(request, response, false, false);
- }
-
- /**
- * Constructs a new report using the provided locale for the output language.<p>
- *
- * @param request HttpServletRequest
- * @param response HttpServletResponse
- * @param writeHtml if <code>true</code>, this report should generate HTML instead of JavaScript output
- * @param isTransient If set to <code>true</code> nothing is kept in memory
- */
- public HtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
-
- init(UtilHttp.getLocale(request));
- content = new ArrayList<Serializable>(256);
- logContent = new ArrayList<Serializable>(256);
- showExceptionStackTrace = true;
- this.writeHtml = writeHtml;
- this.isTransient = isTransient;
- }
-
- public static HtmlReport getInstance(HttpServletRequest request, HttpServletResponse response) {
- HtmlReport wp = (HtmlReport) request.getSession().getAttribute(SESSION_REPORT_CLASS);
- if (wp == null) {
- wp = new HtmlReport(request, response, true, true);
- request.getSession().setAttribute(SESSION_REPORT_CLASS, wp);
- }
- return wp;
- }
-
- public static HtmlReport getInstance(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
- HtmlReport wp = (HtmlReport) request.getSession().getAttribute(SESSION_REPORT_CLASS);
- if (wp == null) {
- wp = new HtmlReport(request, response, writeHtml, isTransient);
- request.getSession().setAttribute(SESSION_REPORT_CLASS, wp);
- }
- return wp;
- }
-
- public static HtmlReport getInstance(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient, String logFileName) {
- HtmlReport wp = (HtmlReport) request.getSession().getAttribute(SESSION_REPORT_CLASS);
- if (wp == null || UtilValidate.isEmpty(wp.getLogFileName()) || !wp.getLogFileName().equals(logFileName)) {
- wp = new HtmlReport(request, response, writeHtml, isTransient);
- request.getSession().setAttribute(SESSION_REPORT_CLASS, wp);
- }
- return wp;
- }
-
- public String getParamAction(HttpServletRequest request) {
- paramAction = request.getParameter("action");
- return paramAction != null ? paramAction : "reportbegin";
- }
-
- public void setParamAction(String action) {
- paramAction = action;
- }
-
- public void setParamThread(String name) {
- paramThread = name;
- }
-
- public synchronized String getReportUpdate() {
- StringBuffer result = new StringBuffer();
- StringBuffer logResult = new StringBuffer();
- int indexEnd = content.size();
- for (int i = indexNext; i < indexEnd; i++) {
- int pos = isTransient ? 0 : i;
- Object obj = content.get(pos);
- if ((obj instanceof String) || (obj instanceof StringBuffer)) {
- result.append(obj);
- } else if (obj instanceof Throwable) {
- result.append(getExceptionElementJS((Throwable)obj));
- }
- if (isTransient) {
- content.remove(indexNext);
- }
- if (UtilValidate.isNotEmpty(logContent)) {
- Object logObj = logContent.get(pos);
- if ((logObj instanceof String) || (logObj instanceof StringBuffer)) {
- logResult.append(logObj);
- } else if (logObj instanceof Throwable) {
- result.append(getExceptionElementHtml((Throwable) logObj));
- }
- if (isTransient) {
- logContent.remove(indexNext);
- }
- }
- }
-
- indexNext = isTransient ? 0 : indexEnd;
-
- if (isTransient && logFileOutputStream != null && logResult.toString().length() > 0) {
- try {
- logFileOutputStream.write((logResult.toString() + "\n").getBytes());
- logFileOutputStream.flush();
- } catch (IOException e) {
- Debug.logError(e.getMessage(), module);
- }
- }
- return result.toString();
- }
-
- /**
- * Returns if the report writes html or javascript code.<p>
- *
- * @return <code>true</code> if the report writes html, and <code>false</code> if the report writes javascript code
- */
- public boolean isWriteHtml() {
- return writeHtml;
- }
-
- public synchronized void print(String value, int format) {
- StringBuffer buf = null;
- value = ReportStringUtil.escapeJavaScript(value);
- switch (format) {
- case FORMAT_HEADLINE:
- buf = new StringBuffer();
- buf.append("aH('");
- buf.append(value);
- buf.append("'); ");
- break;
- case FORMAT_WARNING:
- buf = new StringBuffer();
- buf.append("aW('");
- buf.append(value);
- buf.append("'); ");
- addWarning(value);
- break;
- case FORMAT_ERROR:
- buf = new StringBuffer();
- buf.append("aE('");
- buf.append(value);
- buf.append("'); ");
- addError(value);
- break;
- case FORMAT_NOTE:
- buf = new StringBuffer();
- buf.append("aN('");
- buf.append(value);
- buf.append("'); ");
- break;
- case FORMAT_OK:
- buf = new StringBuffer();
- buf.append("aO('");
- buf.append(value);
- buf.append("'); ");
- break;
- case FORMAT_DEFAULT:
- default:
- buf = new StringBuffer();
- buf.append("a('");
- buf.append(value);
- buf.append("'); ");
- }
- if (value.trim().endsWith(getLineBreak())) {
- buf.append("aB(); ");
- }
- content.add(buf.toString());
-
- switch (format) {
- case FORMAT_HEADLINE:
- buf = new StringBuffer();
- buf.append("<span class='head'>");
- buf.append(value);
- buf.append("</span>");
- break;
- case FORMAT_WARNING:
- buf = new StringBuffer();
- buf.append("<span class='warn'>");
- buf.append(value);
- buf.append("</span>");
- addWarning(value);
- break;
- case FORMAT_ERROR:
- buf = new StringBuffer();
- buf.append("<span class='err'>");
- buf.append(value);
- buf.append("</span>");
- addError(value);
- break;
- case FORMAT_NOTE:
- buf = new StringBuffer();
- buf.append("<span class='note'>");
- buf.append(value);
- buf.append("</span>");
- break;
- case FORMAT_OK:
- buf = new StringBuffer();
- buf.append("<span class='ok'>");
- buf.append(value);
- buf.append("</span>");
- break;
- case FORMAT_DEFAULT:
- default:
- buf = new StringBuffer(value);
- }
- if (value.trim().endsWith(getLineBreak())) {
- buf.append("\n");
- }
- logContent.add(buf.toString());
- }
-
- public void println() {
- print(getLineBreak());
- }
-
- public synchronized void println(Throwable t) {
- addError(t.getMessage());
- content.add(getExceptionElementJS(t));
- logContent.add(getExceptionElementHtml(t));
- }
-
- /**
- * Returns the correct line break notation depending on the output style of this report.
- *
- * @return the correct line break notation
- */
- protected String getLineBreak() {
- return writeHtml ? LINEBREAK_TRADITIONAL : LINEBREAK;
- }
-
- /**
- * Output helper method to format a reported <code>Throwable</code> element.<p>
- *
- * This method ensures that exception stack traces are properly escaped
- * when they are added to the report.<p>
- *
- * There is a member variable {@link #showExceptionStackTrace} in this
- * class that controls if the stack track is shown or not.
- * In a later version this might be configurable on a per-user basis.<p>
- *
- * @param throwable the exception to format
- * @return the formatted StringBuffer
- */
- private StringBuffer getExceptionElementJS(Throwable throwable) {
- StringBuffer buf = new StringBuffer(256);
- if (showExceptionStackTrace) {
- buf.append("aT('");
- buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
- String exception = ReportEncoder.escapeXml(throwable.getLocalizedMessage());
- if (UtilValidate.isEmpty(exception)) {
- exception = ReportEncoder.escapeXml(throwable.getMessage());
- }
- if (UtilValidate.isNotEmpty(exception)) {
- exception = exception.replaceAll("[\r\n]+", LINEBREAK);
- buf.append(ReportStringUtil.escapeJavaScript(exception) + LINEBREAK);
- } else {
- buf.append(throwable.toString());
- }
- buf.append("'); ");
- } else {
- buf.append("aT('");
- buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
- buf.append(ReportStringUtil.escapeJavaScript(throwable.toString()));
- buf.append("'); ");
- }
- return buf;
- }
-
- private StringBuffer getExceptionElementHtml(Throwable throwable) {
- StringBuffer buf = new StringBuffer(256);
- if (showExceptionStackTrace) {
- buf.append("<span class='throw'>");
- buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
- String exception = ReportEncoder.escapeXml(throwable.getLocalizedMessage());
- if (UtilValidate.isEmpty(exception)) {
- exception = ReportEncoder.escapeXml(throwable.getMessage());
- }
- if (UtilValidate.isNotEmpty(exception)) {
- exception = exception.replaceAll("[\r\n]+", LINEBREAK);
- buf.append(exception);
- } else {
- buf.append(throwable.toString());
- }
- buf.append("</span>");
- } else {
- buf.append("<span class='throw'>");
- buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
- buf.append(throwable.toString());
- buf.append("</span>");
- buf.append(getLineBreak());
- }
- return buf;
- }
-
- public void printMessageWithParam(String uiLabel, Object param) {
- print(uiLabel, InterfaceReport.FORMAT_NOTE);
- }
-
- public void printMessageWithParam(int m, int n, String uiLabel, Object param) {
- print(uiLabel, InterfaceReport.FORMAT_NOTE);
- }
-
- /**
- * Builds the start html of the page, including setting of DOCTYPE and
- * inserting a header with the content-type.<p>
- *
- * This overloads the default method of the parent class.<p>
- *
- * @return the start html of the page
- */
- public String htmlStart() {
-
- return pageHtml(HTML_START, true);
- }
-
- /**
- * Builds the start html of the page, including setting of DOCTYPE and
- * inserting a header with the content-type.<p>
- *
- * This overloads the default method of the parent class.<p>
- *
- * @param loadStyles if true, the defaul style sheet will be loaded
- * @return the start html of the page
- */
- public String htmlStart(boolean loadStyles) {
-
- return pageHtml(HTML_START, loadStyles);
- }
-
- /**
- * Builds the start html of the page, including setting of DOCTYPE and
- * inserting a header with the content-type.<p>
- *
- * This overloads the default method of the parent class.<p>
- *
- * @param segment the HTML segment (START / END)
- * @param loadStyles if true, the defaul style sheet will be loaded
- * @return the start html of the page
- */
- public String pageHtml(int segment, boolean loadStyles) {
- if (segment == HTML_START) {
- StringBuffer result = new StringBuffer(512);
- result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n");
- result.append("<html>\n<head>\n");
- result.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n");
- if (loadStyles) {
- result.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
- result.append("/pricat/includes/pricat.css");
- result.append("\">\n");
- result.append("<script type=\"text/javascript\">\n");
- result.append(dialogScriptSubmit());
- result.append("</script>\n");
- }
- return result.toString();
- } else {
- return "</html>";
- }
- }
-
- /**
- * Builds the standard javascript for submitting the dialog.<p>
- *
- * @return the standard javascript for submitting the dialog
- */
- public String dialogScriptSubmit() {
- StringBuffer result = new StringBuffer(512);
- result.append("function submitAction(actionValue, theForm, formName) {\n");
- result.append("\tif (theForm == null) {\n");
- result.append("\t\ttheForm = document.forms[formName];\n");
- result.append("\t}\n");
- result.append("\ttheForm.action.value = actionValue;\n");
- result.append("\ttheForm.submit();\n");
- result.append("\treturn false;\n");
- result.append("}\n");
- return result.toString();
- }
-
- /**
- * Returns true if the report Thread is still alive (i.e. running), false otherwise.<p>
- *
- * @return true if the report Thread is still alive
- */
- public boolean isAlive(HttpServletRequest request) {
- ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
- int i = threadGroup.activeCount();
- Thread[] threads = new Thread[i];
- threadGroup.enumerate(threads, true);
- AbstractReportThread thread = null;
- for (int j=0; j<threads.length; j++) {
- Thread threadInstance = threads[j];
- if (threadInstance instanceof AbstractReportThread) {
- if(((AbstractReportThread)threadInstance).getUUID().toString().equals(getParamThread(request))) {
- thread = (AbstractReportThread) threadInstance;
- break;
- }
- }
- }
- if (thread != null) {
- return thread.isAlive();
- } else {
- return false;
- }
- }
-
- /**
- * Returns the thread parameter value.<p>
- *
- * @return the thread parameter value
- */
- public String getParamThread(HttpServletRequest request) {
- String thread = request.getParameter("thread");
- return ReportStringUtil.isNotEmptyOrWhitespaceOnly(thread) ? thread : (paramThread == null? "" : paramThread);
- }
-
- /**
- * Returns the threadhasnext parameter value.<p>
- *
- * @return the threadhasnext parameter value
- */
- public String getParamThreadHasNext(HttpServletRequest request) {
- String threadhasnext = request.getParameter("threadhasnext");
- return ReportStringUtil.isNotEmptyOrWhitespaceOnly(threadhasnext) ? threadhasnext : "false";
- }
-
- /**
- * Builds the start html of the body.<p>
- *
- * @param className optional class attribute to add to the body tag
- * @param parameters optional parameters to add to the body tag
- * @return the start html of the body
- */
- public String bodyStart(String className, String parameters) {
- return pageBody(HTML_START, className, parameters);
- }
-
- /**
- * Builds the html of the body.<p>
- *
- * @param segment the HTML segment (START / END)
- * @param className optional class attribute to add to the body tag
- * @param parameters optional parameters to add to the body tag
- * @return the html of the body
- */
- public String pageBody(int segment, String className, String parameters) {
- if (segment == HTML_START) {
- StringBuffer result = new StringBuffer(128);
- result.append("</head>\n<body unselectable=\"on\"");
- if (ReportStringUtil.isNotEmptyOrWhitespaceOnly(className)) {
- result.append(" class=\"");
- result.append(className);
- result.append("\"");
- }
- if (ReportStringUtil.isNotEmpty(parameters)) {
- result.append(" ");
- result.append(parameters);
- }
- result.append(">\n");
- return result.toString();
- } else {
- return "</body>";
- }
- }
-
- /**
- * Builds the end html of the body.<p>
- *
- * @return the end html of the body
- */
- public String bodyEnd() {
- return pageBody(HTML_END, null, null);
- }
-
- /**
- * Builds the end html of the page.<p>
- *
- * @return the end html of the page
- */
- public String htmlEnd() {
- return pageHtml(HTML_END, null);
- }
-
- /**
- * Returns the default html for a workplace page, including setting of DOCTYPE and
- * inserting a header with the content-type.<p>
- *
- * @param segment the HTML segment (START / END)
- * @param title the title of the page, if null no title tag is inserted
- * @return the default html for a workplace page
- */
- public String pageHtml(int segment, String title) {
- return pageHtmlStyle(segment, title, null);
- }
-
- /**
- * Returns the default html for a workplace page, including setting of DOCTYPE and
- * inserting a header with the content-type, allowing the selection of an individual style sheet.<p>
- *
- * @param segment the HTML segment (START / END)
- * @param title the title of the page, if null no title tag is inserted
- * @param stylesheet the used style sheet, if null the default stylesheet 'workplace.css' is inserted
- * @return the default html for a workplace page
- */
- public String pageHtmlStyle(int segment, String title, String stylesheet) {
- if (segment == HTML_START) {
- StringBuffer result = new StringBuffer(512);
-// result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n");
-// result.append("<html>\n<head>\n");
-// if (title != null) {
-// result.append("<title>");
-// result.append(title);
-// result.append("</title>\n");
-// }
-// result.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n");
- result.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
- result.append("/pricat/includes/pricat.css");
- result.append("\">\n");
- return result.toString();
- } else {
- return "";
-// return "</html>";
- }
- }
-
- /**
- * Returns the start html for the outer dialog window border.
- *
- * @return the start html for the outer dialog window border
- */
- public String dialogStart() {
- return dialog(HTML_START, null);
- }
-
- /**
- * Builds the outer dialog window border.
- *
- * @param segment the HTML segment (START / END)
- * @param attributes optional additional attributes for the opening dialog table
- *
- * @return a dialog window start / end segment
- */
- public String dialog(int segment, String attributes) {
- if (segment == HTML_START) {
- StringBuffer html = new StringBuffer(512);
- html.append("<table class=\"dialog\" cellpadding=\"0\" cellspacing=\"0\"");
- if (attributes != null) {
- html.append(" ");
- html.append(attributes);
- }
- html.append("><tr><td>\n<table class=\"dialogbox\" cellpadding=\"0\" cellspacing=\"0\">\n");
- html.append("<tr><td>\n");
- return html.toString();
- } else {
- return "</td></tr></table>\n</td></tr></table>\n<p> </p>\n";
- }
- }
-
- /**
- * Returns the start html for the content area of the dialog window.<p>
- *
- * @param title the title for the dialog
- *
- * @return the start html for the content area of the dialog window
- */
- public String dialogContentStart(String title) {
- return dialogContent(HTML_START, title);
- }
-
- /**
- * Builds the content area of the dialog window.<p>
- *
- * @param segment the HTML segment (START / END)
- * @param title the title String for the dialog window
- *
- * @return a content area start / end segment
- */
- public String dialogContent(int segment, String title) {
- if (segment == HTML_START) {
- StringBuffer result = new StringBuffer(512);
- // null title is ok, we always want the title headline
- result.append(dialogHead(title));
- result.append("<div class=\"dialogcontent\" unselectable=\"on\">\n");
- result.append("<!-- dialogcontent start -->\n");
- return result.toString();
- } else {
- return "<!-- dialogcontent end -->\n</div>\n";
- }
- }
-
- /**
- * Builds the title of the dialog window.<p>
- *
- * @param title the title String for the dialog window
- *
- * @return the HTML title String for the dialog window
- */
- public String dialogHead(String title) {
- return "<div class=\"dialoghead\" unselectable=\"on\">" + (title == null ? "" : title) + "</div>";
- }
-
- /**
- * Returns the value of the title parameter,
- * or null if this parameter was not provided.<p>
- *
- * This parameter is used to build the title
- * of the dialog. It is a parameter so that the title
- * can be passed to included elements.<p>
- *
- * @return the value of the title parameter
- */
- public String getParamTitle(HttpServletRequest request) {
- if (paramTitle == null) {
- paramTitle = request.getParameter("title");
- }
- return paramTitle != null ? paramTitle : "";
- }
-
- /**
- * Returns all initialized parameters of the current workplace class
- * as hidden field tags that can be inserted in a form.<p>
- *
- * @return all initialized parameters of the current workplace class
- * as hidden field tags that can be inserted in a html form
- */
- public String paramsAsHidden(HttpServletRequest request) {
- return paramsAsHidden(request, null);
- }
-
- /**
- * Returns all initialized parameters of the current workplace class
- * that are not in the given exclusion list as hidden field tags that can be inserted in a form.<p>
- *
- * @param excludes the parameters to exclude
- *
- * @return all initialized parameters of the current workplace class
- * that are not in the given exclusion list as hidden field tags that can be inserted in a form
- */
- public String paramsAsHidden(HttpServletRequest request, Collection<?> excludes) {
- StringBuffer result = new StringBuffer(512);
- Map<String, Object> params = paramValues(request);
- Iterator<?> i = params.entrySet().iterator();
- while (i.hasNext()) {
- Map.Entry entry = (Map.Entry)i.next();
- String param = (String)entry.getKey();
- if ((excludes == null) || (!excludes.contains(param))) {
- result.append("<input type=\"hidden\" name=\"");
- result.append(param);
- result.append("\" value=\"");
- String encoded = ReportEncoder.encode(
- entry.getValue().toString(),
- "UTF-8");
- result.append(encoded);
- result.append("\">\n");
- }
- }
-
- return result.toString();
- }
-
- /**
- * Returns the values of all parameter methods of this workplace class instance.<p>
- *
- * @return the values of all parameter methods of this workplace class instance
- */
- protected Map<String, Object> paramValues(HttpServletRequest request) {
- List<Method> methods = paramGetMethods();
- Map<String, Object> map = new HashMap<String, Object>(methods.size());
- Iterator<Method> i = methods.iterator();
- while (i.hasNext()) {
- Method m = (Method)i.next();
- Object o = null;
- try {
- o = m.invoke(this, new Object[0]);
- } catch (InvocationTargetException ite) {
- // can usually be ignored
- } catch (IllegalAccessException eae) {
- // can usually be ignored
- }
- if (o != null) {
- map.put(m.getName().substring(8).toLowerCase(), o);
- }
- }
- return map;
- }
-
- /**
- * Returns a list of all methods of the current class instance that
- * start with "getParam" and have no parameters.<p>
- *
- * @return a list of all methods of the current class instance that
- * start with "getParam" and have no parameters
- */
- private List<Method> paramGetMethods() {
- List<Method> list = new ArrayList<Method>();
- Method[] methods = this.getClass().getMethods();
- int length = methods.length;
- for (int i = 0; i < length; i++) {
- Method method = methods[i];
- if (method.getName().startsWith("getParam") && (method.getParameterTypes().length == 0)) {
- // Debug.logInfo("getMethod: " + method.getName(), module);
- list.add(method);
- }
- }
- return list;
- }
-
- /**
- * Returns an optional introduction text to be displayed above the report output.<p>
- *
- * @return an optional introduction text
- */
- public String reportIntroductionText() {
- return "";
- }
-
- /**
- * Returns an optional conclusion text to be displayed below the report output.<p>
- *
- * @return an optional conclusion text
- */
- public String reportConclusionText() {
- return "";
- }
-
- /**
- * Returns the end html for the content area of the dialog window.<p>
- *
- * @return the end html for the content area of the dialog window
- */
- public String dialogContentEnd() {
- return dialogContent(HTML_END, null);
- }
-
- /**
- * Builds a button row with an "Ok" and a "Cancel" button.<p>
- *
- * This row is displayed when the first report is running.<p>
- *
- * @param okAttrs optional attributes for the ok button
- * @param cancelAttrs optional attributes for the cancel button
- * @return the button row
- */
- public String dialogButtonsContinue(String okAttrs, String cancelAttrs) {
- return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[] {
- okAttrs,
- cancelAttrs});
- }
-
- /**
- * Builds a button row with an "OK" and a "Cancel" button.<p>
- *
- * This row is used when a single report is running or after the first report has finished.<p>
- *
- * @param okAttrs optional attributes for the ok button
- * @param cancelAttrs optional attributes for the cancel button
- * @return the button row
- */
- public String dialogButtonsOkCancel(HttpServletRequest request, String okAttrs, String cancelAttrs) {
- if (Boolean.valueOf(getParamThreadHasNext(request)).booleanValue()
- && ReportStringUtil.isNotEmpty(getParamReportContinueKey())) {
- return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[] {
- okAttrs,
- cancelAttrs});
- }
- return dialogButtons(new int[] {BUTTON_OK}, new String[] {okAttrs});
- }
-
- /**
- * Builds a button row with an "OK", a "Cancel" and a "Download" button.<p>
- *
- * This row is used when a single report is running or after the first report has finished.<p>
- *
- * @param okAttrs optional attributes for the ok button
- * @param cancelAttrs optional attributes for the cancel button
- * @param downloadAttrs optional attributes for the download button
- * @return the button row
- */
- public String dialogButtonsOkCancelDownload(HttpServletRequest request, String okAttrs, String cancelAttrs, String downloadAttrs) {
- if (ReportStringUtil.isEmptyOrWhitespaceOnly(downloadAttrs)) {
- downloadAttrs = "";
- } else {
- downloadAttrs += " ";
- }
- if (Boolean.valueOf(getParamThreadHasNext(request)).booleanValue()
- && ReportStringUtil.isNotEmpty(getParamReportContinueKey())) {
- return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL, BUTTON_DOWNLOAD}, new String[] {
- okAttrs,
- cancelAttrs,
- downloadAttrs + "onclick=\"downloadPricat(" + (sequenceNum > 0 ? sequenceNum : "") + ");\""});
- }
- return dialogButtons(new int[] {BUTTON_OK, BUTTON_DOWNLOAD}, new String[] {
- okAttrs,
- downloadAttrs + "onclick=\"downloadPricat(" + (sequenceNum > 0 ? sequenceNum : "") + ");\""});
- }
-
- /**
- * Builds the html for the button row under the dialog content area, including buttons.<p>
- *
- * @param buttons array of constants of which buttons to include in the row
- * @param attributes array of Strings for additional button attributes
- *
- * @return the html for the button row under the dialog content area, including buttons
- */
- public String dialogButtons(int[] buttons, String[] attributes) {
- StringBuffer result = new StringBuffer(256);
- result.append(dialogButtonRow(HTML_START));
- for (int i = 0; i < buttons.length; i++) {
- dialogButtonsHtml(result, buttons[i], attributes[i]);
- }
- result.append(dialogButtonRow(HTML_END));
- return result.toString();
- }
-
- /**
- * Builds the button row under the dialog content area without the buttons.<p>
- *
- * @param segment the HTML segment (START / END)
- *
- * @return the button row start / end segment
- */
- public String dialogButtonRow(int segment) {
- if (segment == HTML_START) {
- return "<!-- button row start -->\n<div class=\"dialogbuttons\" unselectable=\"on\">\n";
- } else {
- return "</div>\n<!-- button row end -->\n";
- }
- }
-
- /**
- * Renders the HTML for a single input button of a specified type.<p>
- *
- * @param result a string buffer where the rendered HTML gets appended to
- * @param button a integer key to identify the button
- * @param attribute an optional string with possible tag attributes, or null
- */
- protected void dialogButtonsHtml(StringBuffer result, int button, String attribute) {
- attribute = appendDelimiter(attribute);
- switch (button) {
- case BUTTON_OK:
- result.append("<input name=\"ok\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_OK", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" type=\"submit\"");
- } else {
- result.append(" type=\"button\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_CANCEL:
- result.append("<input name=\"cancel\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_CANCEL", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_EDIT:
- result.append("<input name=\"ok\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_EDIT", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" type=\"submit\"");
- } else {
- result.append(" type=\"button\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_DISCARD:
- result.append("<input name=\"cancel\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_DISCARD", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_CLOSE:
- result.append("<input name=\"close\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_CLOSE", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_ADVANCED:
- result.append("<input name=\"advanced\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_ADVANCE", getLocale()) + "\"");
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_SET:
- result.append("<input name=\"set\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_SET", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" onclick=\"submitAction('" + DIALOG_SET + "', form);\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_BACK:
- result.append("<input name=\"set\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_BACK", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" onclick=\"submitAction('" + DIALOG_BACK + "', form);\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_CONTINUE:
- result.append("<input name=\"set\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_CONTINUE", getLocale()) + "\"");
- if (attribute.toLowerCase().indexOf("onclick") == -1) {
- result.append(" onclick=\"submitAction('" + DIALOG_CONTINUE + "', form);\"");
- }
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_DETAILS:
- result.append("<input name=\"details\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_DETAIL", getLocale()) + "\"");
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- case BUTTON_DOWNLOAD:
- result.append("<input name=\"download\" type=\"button\" value=\"");
- result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_DOWNLOAD", getLocale()) + "\"");
- result.append(" class=\"dialogbutton\"");
- result.append(attribute);
- result.append(">\n");
- break;
- default:
- // not a valid button code, just insert a warning in the HTML
- result.append("<!-- invalid button code: ");
- result.append(button);
- result.append(" -->\n");
- }
- }
-
- /**
- * Appends a space char. between tag attributes.<p>
- *
- * @param attribute a tag attribute
- *
- * @return the tag attribute with a leading space char
- */
- protected String appendDelimiter(String attribute) {
- if (ReportStringUtil.isNotEmpty(attribute)) {
- if (!attribute.startsWith(" ")) {
- // add a delimiter space between the beginning button HTML and the button tag attributes
- return " " + attribute;
- } else {
- return attribute;
- }
- }
- return "";
- }
-
- /**
- * Returns true if the dialog operation has to be performed on multiple resources.<p>
- *
- * @return true if the dialog operation has to be performed on multiple resources, otherwise false
- */
- public boolean isMultiOperation(HttpServletRequest request) {
- return (getResourceList(request).size() > 1);
- }
-
- /**
- * Returns the resources that are defined for the dialog operation.
- *
- * For single resource operations, the list contains one item: the resource name found
- * in the request parameter value of the "resource" parameter.
- *
- * @return the resources that are defined for the dialog operation
- */
- public List<String> getResourceList(HttpServletRequest request) {
- if (resourceList == null) {
- // use lazy initializing
- if (getParamResourcelist(request) != null) {
- // found the resourcelist parameter
- resourceList = StringUtil.split(getParamResourcelist(request), DELIMITER_RESOURCES);
- Collections.sort(resourceList);
- } else {
- // this is a single resource operation, create list containing the resource name
- resourceList = new ArrayList<String>(1);
- String resource = getParamResource(request);
- if (ReportStringUtil.isNotEmptyOrWhitespaceOnly(resource)) {
- resourceList.add(resource);
- } else {
- resourceList.add("");
- }
- }
- }
- return resourceList;
- }
-
- /**
- * Returns the value of the resource list parameter, or null if the parameter is not provided.<p>
- *
- * This parameter selects the resources to perform operations on.<p>
- *
- * @return the value of the resource list parameter or null, if the parameter is not provided
- */
- public String getParamResourcelist(HttpServletRequest request) {
- if (ReportStringUtil.isNotEmpty(paramResourcelist) && !"null".equals(paramResourcelist)) {
- return paramResourcelist;
- } else {
- return null;
- }
- }
-
- /**
- * Returns the value of the file parameter,
- * or null if this parameter was not provided.<p>
- *
- * The file parameter selects the file on which the dialog action
- * is to be performed.<p>
- *
- * @return the value of the file parameter
- */
- public String getParamResource(HttpServletRequest request) {
- paramResource = request.getParameter("resource");
- if ((paramResource != null) && !"null".equals(paramResource)) {
- return paramResource;
- } else {
- return null;
- }
- }
-
- /**
- * Returns if the workplace must be refreshed.<p>
- *
- * @return <code>"true"</code> if the workplace must be refreshed.
- */
- public String getParamRefreshWorkplace() {
- return paramRefreshWorkplace;
- }
-
- /**
- * Returns the key name which contains the localized message for the continue checkbox.<p>
- *
- * @return the key name which contains the localized message for the continue checkbox
- */
- public String getParamReportContinueKey() {
- if (paramReportContinueKey == null) {
- paramReportContinueKey = "";
- }
- return paramReportContinueKey;
- }
-
- /**
- * Returns the value of the resourcelist parameter in form of a String separated
- * with {@link #DELIMITER_RESOURCES}, or the value of the resource parameter if the
- * first parameter is not provided (no multiple choice has been done.<p>
- *
- * This may be used for jsps as value for the parameter for resources {@link #PARAM_RESOURCELIST}.<p>
- *
- * @return the value of the resourcelist parameter or null, if the parameter is not provided
- */
- public String getResourceListAsParam(HttpServletRequest request) {
- String result = getParamResourcelist(request);
- if (ReportStringUtil.isEmptyOrWhitespaceOnly(result)) {
- result = getParamResource(request);
- }
- return result;
- }
-
- /**
- * Returns the end html for the outer dialog window border.<p>
- *
- * @return the end html for the outer dialog window border
- */
- public String dialogEnd() {
- return dialog(HTML_END, null);
- }
-
- /**
- * Returns the http URI of the current dialog, to be used
- * as value for the "action" attribute of a html form.<p>
- *
- * This URI is the real one.<p>
- *
- * @return the http URI of the current dialog
- */
- public String getDialogRealUri(HttpServletRequest request) {
- return String.valueOf(request.getAttribute(DIALOG_URI));
- }
-
- /**
- * Set the report form uri.
- *
- * @param request
- * @param formUri
- */
- public void setFormRealUri(HttpServletRequest request, String formUri) {
- request.setAttribute(FORM_URI, formUri);
- }
-
- /**
- * Get the report form uri.
- *
- * @param request
- * @return
- */
- public String getFormRealUri(HttpServletRequest request) {
- return (String) request.getAttribute(FORM_URI);
- }
-
- public void addLogFile(String logFileName) {
- if (logFile == null || logFileOutputStream == null) {
- this.logFileName = logFileName;
- logFile = FileUtil.getFile(logFileName);
- try {
- logFileOutputStream = new FileOutputStream(logFile);
- } catch (FileNotFoundException e) {
- // do nothing
- }
- }
- }
-
- public String closeLogFile() {
- if (logFileOutputStream != null) {
- try {
- logFileOutputStream.flush();
- } catch (IOException e) {
- // do nothing
- } finally {
- if (logFileOutputStream != null) {
- try {
- logFileOutputStream.close();
- } catch (IOException e) {
- // do nothing
- Debug.logError(e, HtmlReport.module);
- }
- }
- }
- }
- return logFileName;
- }
-
- public String getLogFileName() {
- return logFileName;
- }
-
- public long getSequenceNum() {
- return sequenceNum;
- }
-
- public void setSequenceNum(long sequenceNum) {
- this.sequenceNum = sequenceNum;
- }
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.FileUtil;
+import org.apache.ofbiz.base.util.StringUtil;
+import org.apache.ofbiz.base.util.UtilHttp;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.htmlreport.util.ReportEncoder;
+import org.apache.ofbiz.htmlreport.util.ReportStringUtil;
+
+/**
+ * HTML report output to be used in report.ftl.<p>
+ *
+ */
+public class HtmlReport extends AbstractReport {
+
+ public static final String module = HtmlReport.class.getName();
+
+ /** The delimiter that is used in the resource list request parameter. */
+ public static final String DELIMITER_RESOURCES = "|";
+
+ /** Request parameter name for the resource list. */
+ public static final String PARAM_RESOURCELIST = "resourcelist";
+
+ /** Constant for a HTML linebreak with added "real" line break. */
+ protected static final String LINEBREAK = "<br>";
+
+ /**
+ * Constant for a HTML linebreak with added "real" line break-
+ * traditional style for report threads that still use XML templates for their output.
+ */
+ protected static final String LINEBREAK_TRADITIONAL = "<br>\n";
+
+ /** The list of report objects e.g. String, Exception ... */
+ protected List<Serializable> content;
+
+ /** The list of report objects e.g. String, Exception ... */
+ protected List<Serializable> logContent;
+
+ /**
+ * Counter to remember what is already shown,
+ * indicates the next index of the content list that has to be reported.
+ */
+ protected int indexNext;
+
+ /** Flag to indicate if an exception should be displayed long or short. */
+ protected boolean showExceptionStackTrace;
+
+ /** If set to <code>true</code> nothing is kept in memory. */
+ protected boolean isTransient;
+
+ /** Boolean flag indicating whether this report should generate HTML or JavaScript output. */
+ protected boolean writeHtml;
+
+ /** Helper variable to deliver the html end part. */
+ public static final int HTML_END = 1;
+
+ /** Helper variable to deliver the html start part. */
+ public static final int HTML_START = 0;
+
+ /** The thread to display in this report. */
+ protected String paramThread;
+
+ /** The next thread to display after this report. */
+ protected String paramThreadHasNext;
+
+ protected String paramAction;
+
+ protected String paramTitle;
+
+ protected String paramResource;
+
+ /** Flag for refreching workplace .*/
+ protected String paramRefreshWorkplace;
+
+ /** Constant for the "OK" button in the build button methods. */
+ public static final int BUTTON_OK = 0;
+
+ /** Constant for the "Cancel" button in the build button methods. */
+ public static final int BUTTON_CANCEL = 1;
+
+ /** Constant for the "Close" button in the build button methods. */
+ public static final int BUTTON_CLOSE = 2;
+
+ /** Constant for the "Advanced" button in the build button methods. */
+ public static final int BUTTON_ADVANCED = 3;
+
+ /** Constant for the "Set" button in the build button methods. */
+ public static final int BUTTON_SET = 4;
+
+ /** Constant for the "Details" button in the build button methods. */
+ public static final int BUTTON_DETAILS = 5;
+
+ /** Constant for the "OK" button in the build button methods (without form submission). */
+ public static final int BUTTON_OK_NO_SUBMIT = 6;
+
+ /** Constant for the "Edit" button in the build button methods (same function as "Ok" button but different text on button. */
+ public static final int BUTTON_EDIT = 7;
+
+ /** Constant for the "Discard" button in the build button methods (same function as "Cancel" button but different text on button. */
+ public static final int BUTTON_DISCARD = 8;
+
+ /** Constant for the "Back" button in the build button methods. */
+ public static final int BUTTON_BACK = 9;
+
+ /** Constant for the "Continue" button in the build button methods. */
+ public static final int BUTTON_CONTINUE = 10;
+
+ /** Constant for the "Download" button in the build button methods. */
+ public static final int BUTTON_DOWNLOAD = 11;
+
+ /** Request parameter value for the action: back. */
+ public static final String DIALOG_BACK = "back";
+
+ /** Request parameter value for the action: cancel. */
+ public static final String DIALOG_CANCEL = "cancel";
+
+ /** Request parameter value for the action: continue. */
+ public static final String DIALOG_CONTINUE = "continue";
+
+ /** Request parameter value for the action: set. */
+ public static final String DIALOG_SET = "set";
+
+ /** The resource list parameter value. */
+ protected String paramResourcelist;
+
+ /** The list of resource names for the multi operation. */
+ protected List<String> resourceList;
+
+ /** The key name which contains the localized message for the continue checkbox. */
+ protected String paramReportContinueKey;
+
+ public static final String DIALOG_URI = "dialoguri";
+
+ public static final String FORM_URI = "formuri";
+
+ public static final String resource = "PricatUiLabels";
+
+ /** Log file. */
+ protected File logFile;
+
+ /** Log file name. */
+ protected String logFileName;
+
+ /** Log file output stream. */
+ protected FileOutputStream logFileOutputStream;
+
+ protected long sequenceNum = -1;
+
+ /**
+ * Constructs a new report using the provided locale for the output language.<p>
+ *
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ */
+ public HtmlReport(HttpServletRequest request, HttpServletResponse response) {
+
+ this(request, response, false, false);
+ }
+
+ /**
+ * Constructs a new report using the provided locale for the output language.<p>
+ *
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @param writeHtml if <code>true</code>, this report should generate HTML instead of JavaScript output
+ * @param isTransient If set to <code>true</code> nothing is kept in memory
+ */
+ public HtmlReport(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
+
+ init(UtilHttp.getLocale(request));
+ content = new ArrayList<Serializable>(256);
+ logContent = new ArrayList<Serializable>(256);
+ showExceptionStackTrace = true;
+ this.writeHtml = writeHtml;
+ this.isTransient = isTransient;
+ }
+
+ public static HtmlReport getInstance(HttpServletRequest request, HttpServletResponse response) {
+ HtmlReport wp = (HtmlReport) request.getSession().getAttribute(SESSION_REPORT_CLASS);
+ if (wp == null) {
+ wp = new HtmlReport(request, response, true, true);
+ request.getSession().setAttribute(SESSION_REPORT_CLASS, wp);
+ }
+ return wp;
+ }
+
+ public static HtmlReport getInstance(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient) {
+ HtmlReport wp = (HtmlReport) request.getSession().getAttribute(SESSION_REPORT_CLASS);
+ if (wp == null) {
+ wp = new HtmlReport(request, response, writeHtml, isTransient);
+ request.getSession().setAttribute(SESSION_REPORT_CLASS, wp);
+ }
+ return wp;
+ }
+
+ public static HtmlReport getInstance(HttpServletRequest request, HttpServletResponse response, boolean writeHtml, boolean isTransient, String logFileName) {
+ HtmlReport wp = (HtmlReport) request.getSession().getAttribute(SESSION_REPORT_CLASS);
+ if (wp == null || UtilValidate.isEmpty(wp.getLogFileName()) || !wp.getLogFileName().equals(logFileName)) {
+ wp = new HtmlReport(request, response, writeHtml, isTransient);
+ request.getSession().setAttribute(SESSION_REPORT_CLASS, wp);
+ }
+ return wp;
+ }
+
+ public String getParamAction(HttpServletRequest request) {
+ paramAction = request.getParameter("action");
+ return paramAction != null ? paramAction : "reportbegin";
+ }
+
+ public void setParamAction(String action) {
+ paramAction = action;
+ }
+
+ public void setParamThread(String name) {
+ paramThread = name;
+ }
+
+ public synchronized String getReportUpdate() {
+ StringBuffer result = new StringBuffer();
+ StringBuffer logResult = new StringBuffer();
+ int indexEnd = content.size();
+ for (int i = indexNext; i < indexEnd; i++) {
+ int pos = isTransient ? 0 : i;
+ Object obj = content.get(pos);
+ if ((obj instanceof String) || (obj instanceof StringBuffer)) {
+ result.append(obj);
+ } else if (obj instanceof Throwable) {
+ result.append(getExceptionElementJS((Throwable)obj));
+ }
+ if (isTransient) {
+ content.remove(indexNext);
+ }
+ if (UtilValidate.isNotEmpty(logContent)) {
+ Object logObj = logContent.get(pos);
+ if ((logObj instanceof String) || (logObj instanceof StringBuffer)) {
+ logResult.append(logObj);
+ } else if (logObj instanceof Throwable) {
+ result.append(getExceptionElementHtml((Throwable) logObj));
+ }
+ if (isTransient) {
+ logContent.remove(indexNext);
+ }
+ }
+ }
+
+ indexNext = isTransient ? 0 : indexEnd;
+
+ if (isTransient && logFileOutputStream != null && logResult.toString().length() > 0) {
+ try {
+ logFileOutputStream.write((logResult.toString() + "\n").getBytes());
+ logFileOutputStream.flush();
+ } catch (IOException e) {
+ Debug.logError(e.getMessage(), module);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Returns if the report writes html or javascript code.<p>
+ *
+ * @return <code>true</code> if the report writes html, and <code>false</code> if the report writes javascript code
+ */
+ public boolean isWriteHtml() {
+ return writeHtml;
+ }
+
+ public synchronized void print(String value, int format) {
+ StringBuffer buf = null;
+ value = ReportStringUtil.escapeJavaScript(value);
+ switch (format) {
+ case FORMAT_HEADLINE:
+ buf = new StringBuffer();
+ buf.append("aH('");
+ buf.append(value);
+ buf.append("'); ");
+ break;
+ case FORMAT_WARNING:
+ buf = new StringBuffer();
+ buf.append("aW('");
+ buf.append(value);
+ buf.append("'); ");
+ addWarning(value);
+ break;
+ case FORMAT_ERROR:
+ buf = new StringBuffer();
+ buf.append("aE('");
+ buf.append(value);
+ buf.append("'); ");
+ addError(value);
+ break;
+ case FORMAT_NOTE:
+ buf = new StringBuffer();
+ buf.append("aN('");
+ buf.append(value);
+ buf.append("'); ");
+ break;
+ case FORMAT_OK:
+ buf = new StringBuffer();
+ buf.append("aO('");
+ buf.append(value);
+ buf.append("'); ");
+ break;
+ case FORMAT_DEFAULT:
+ default:
+ buf = new StringBuffer();
+ buf.append("a('");
+ buf.append(value);
+ buf.append("'); ");
+ }
+ if (value.trim().endsWith(getLineBreak())) {
+ buf.append("aB(); ");
+ }
+ content.add(buf.toString());
+
+ switch (format) {
+ case FORMAT_HEADLINE:
+ buf = new StringBuffer();
+ buf.append("<span class='head'>");
+ buf.append(value);
+ buf.append("</span>");
+ break;
+ case FORMAT_WARNING:
+ buf = new StringBuffer();
+ buf.append("<span class='warn'>");
+ buf.append(value);
+ buf.append("</span>");
+ addWarning(value);
+ break;
+ case FORMAT_ERROR:
+ buf = new StringBuffer();
+ buf.append("<span class='err'>");
+ buf.append(value);
+ buf.append("</span>");
+ addError(value);
+ break;
+ case FORMAT_NOTE:
+ buf = new StringBuffer();
+ buf.append("<span class='note'>");
+ buf.append(value);
+ buf.append("</span>");
+ break;
+ case FORMAT_OK:
+ buf = new StringBuffer();
+ buf.append("<span class='ok'>");
+ buf.append(value);
+ buf.append("</span>");
+ break;
+ case FORMAT_DEFAULT:
+ default:
+ buf = new StringBuffer(value);
+ }
+ if (value.trim().endsWith(getLineBreak())) {
+ buf.append("\n");
+ }
+ logContent.add(buf.toString());
+ }
+
+ public void println() {
+ print(getLineBreak());
+ }
+
+ public synchronized void println(Throwable t) {
+ addError(t.getMessage());
+ content.add(getExceptionElementJS(t));
+ logContent.add(getExceptionElementHtml(t));
+ }
+
+ /**
+ * Returns the correct line break notation depending on the output style of this report.
+ *
+ * @return the correct line break notation
+ */
+ protected String getLineBreak() {
+ return writeHtml ? LINEBREAK_TRADITIONAL : LINEBREAK;
+ }
+
+ /**
+ * Output helper method to format a reported <code>Throwable</code> element.<p>
+ *
+ * This method ensures that exception stack traces are properly escaped
+ * when they are added to the report.<p>
+ *
+ * There is a member variable {@link #showExceptionStackTrace} in this
+ * class that controls if the stack track is shown or not.
+ * In a later version this might be configurable on a per-user basis.<p>
+ *
+ * @param throwable the exception to format
+ * @return the formatted StringBuffer
+ */
+ private StringBuffer getExceptionElementJS(Throwable throwable) {
+ StringBuffer buf = new StringBuffer(256);
+ if (showExceptionStackTrace) {
+ buf.append("aT('");
+ buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
+ String exception = ReportEncoder.escapeXml(throwable.getLocalizedMessage());
+ if (UtilValidate.isEmpty(exception)) {
+ exception = ReportEncoder.escapeXml(throwable.getMessage());
+ }
+ if (UtilValidate.isNotEmpty(exception)) {
+ exception = exception.replaceAll("[\r\n]+", LINEBREAK);
+ buf.append(ReportStringUtil.escapeJavaScript(exception) + LINEBREAK);
+ } else {
+ buf.append(throwable.toString());
+ }
+ buf.append("'); ");
+ } else {
+ buf.append("aT('");
+ buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
+ buf.append(ReportStringUtil.escapeJavaScript(throwable.toString()));
+ buf.append("'); ");
+ }
+ return buf;
+ }
+
+ private StringBuffer getExceptionElementHtml(Throwable throwable) {
+ StringBuffer buf = new StringBuffer(256);
+ if (showExceptionStackTrace) {
+ buf.append("<span class='throw'>");
+ buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
+ String exception = ReportEncoder.escapeXml(throwable.getLocalizedMessage());
+ if (UtilValidate.isEmpty(exception)) {
+ exception = ReportEncoder.escapeXml(throwable.getMessage());
+ }
+ if (UtilValidate.isNotEmpty(exception)) {
+ exception = exception.replaceAll("[\r\n]+", LINEBREAK);
+ buf.append(exception);
+ } else {
+ buf.append(throwable.toString());
+ }
+ buf.append("</span>");
+ } else {
+ buf.append("<span class='throw'>");
+ buf.append(UtilProperties.getMessage(resource, "REPORT_EXCEPTION", getLocale()));
+ buf.append(throwable.toString());
+ buf.append("</span>");
+ buf.append(getLineBreak());
+ }
+ return buf;
+ }
+
+ public void printMessageWithParam(String uiLabel, Object param) {
+ print(uiLabel, InterfaceReport.FORMAT_NOTE);
+ }
+
+ public void printMessageWithParam(int m, int n, String uiLabel, Object param) {
+ print(uiLabel, InterfaceReport.FORMAT_NOTE);
+ }
+
+ /**
+ * Builds the start html of the page, including setting of DOCTYPE and
+ * inserting a header with the content-type.<p>
+ *
+ * This overloads the default method of the parent class.<p>
+ *
+ * @return the start html of the page
+ */
+ public String htmlStart() {
+
+ return pageHtml(HTML_START, true);
+ }
+
+ /**
+ * Builds the start html of the page, including setting of DOCTYPE and
+ * inserting a header with the content-type.<p>
+ *
+ * This overloads the default method of the parent class.<p>
+ *
+ * @param loadStyles if true, the defaul style sheet will be loaded
+ * @return the start html of the page
+ */
+ public String htmlStart(boolean loadStyles) {
+
+ return pageHtml(HTML_START, loadStyles);
+ }
+
+ /**
+ * Builds the start html of the page, including setting of DOCTYPE and
+ * inserting a header with the content-type.<p>
+ *
+ * This overloads the default method of the parent class.<p>
+ *
+ * @param segment the HTML segment (START / END)
+ * @param loadStyles if true, the defaul style sheet will be loaded
+ * @return the start html of the page
+ */
+ public String pageHtml(int segment, boolean loadStyles) {
+ if (segment == HTML_START) {
+ StringBuffer result = new StringBuffer(512);
+ result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n");
+ result.append("<html>\n<head>\n");
+ result.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n");
+ if (loadStyles) {
+ result.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
+ result.append("/pricat/includes/pricat.css");
+ result.append("\">\n");
+ result.append("<script type=\"text/javascript\">\n");
+ result.append(dialogScriptSubmit());
+ result.append("</script>\n");
+ }
+ return result.toString();
+ } else {
+ return "</html>";
+ }
+ }
+
+ /**
+ * Builds the standard javascript for submitting the dialog.<p>
+ *
+ * @return the standard javascript for submitting the dialog
+ */
+ public String dialogScriptSubmit() {
+ StringBuffer result = new StringBuffer(512);
+ result.append("function submitAction(actionValue, theForm, formName) {\n");
+ result.append("\tif (theForm == null) {\n");
+ result.append("\t\ttheForm = document.forms[formName];\n");
+ result.append("\t}\n");
+ result.append("\ttheForm.action.value = actionValue;\n");
+ result.append("\ttheForm.submit();\n");
+ result.append("\treturn false;\n");
+ result.append("}\n");
+ return result.toString();
+ }
+
+ /**
+ * Returns true if the report Thread is still alive (i.e. running), false otherwise.<p>
+ *
+ * @return true if the report Thread is still alive
+ */
+ public boolean isAlive(HttpServletRequest request) {
+ ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
+ int i = threadGroup.activeCount();
+ Thread[] threads = new Thread[i];
+ threadGroup.enumerate(threads, true);
+ AbstractReportThread thread = null;
+ for (int j=0; j<threads.length; j++) {
+ Thread threadInstance = threads[j];
+ if (threadInstance instanceof AbstractReportThread) {
+ if(((AbstractReportThread)threadInstance).getUUID().toString().equals(getParamThread(request))) {
+ thread = (AbstractReportThread) threadInstance;
+ break;
+ }
+ }
+ }
+ if (thread != null) {
+ return thread.isAlive();
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the thread parameter value.<p>
+ *
+ * @return the thread parameter value
+ */
+ public String getParamThread(HttpServletRequest request) {
+ String thread = request.getParameter("thread");
+ return ReportStringUtil.isNotEmptyOrWhitespaceOnly(thread) ? thread : (paramThread == null? "" : paramThread);
+ }
+
+ /**
+ * Returns the threadhasnext parameter value.<p>
+ *
+ * @return the threadhasnext parameter value
+ */
+ public String getParamThreadHasNext(HttpServletRequest request) {
+ String threadhasnext = request.getParameter("threadhasnext");
+ return ReportStringUtil.isNotEmptyOrWhitespaceOnly(threadhasnext) ? threadhasnext : "false";
+ }
+
+ /**
+ * Builds the start html of the body.<p>
+ *
+ * @param className optional class attribute to add to the body tag
+ * @param parameters optional parameters to add to the body tag
+ * @return the start html of the body
+ */
+ public String bodyStart(String className, String parameters) {
+ return pageBody(HTML_START, className, parameters);
+ }
+
+ /**
+ * Builds the html of the body.<p>
+ *
+ * @param segment the HTML segment (START / END)
+ * @param className optional class attribute to add to the body tag
+ * @param parameters optional parameters to add to the body tag
+ * @return the html of the body
+ */
+ public String pageBody(int segment, String className, String parameters) {
+ if (segment == HTML_START) {
+ StringBuffer result = new StringBuffer(128);
+ result.append("</head>\n<body unselectable=\"on\"");
+ if (ReportStringUtil.isNotEmptyOrWhitespaceOnly(className)) {
+ result.append(" class=\"");
+ result.append(className);
+ result.append("\"");
+ }
+ if (ReportStringUtil.isNotEmpty(parameters)) {
+ result.append(" ");
+ result.append(parameters);
+ }
+ result.append(">\n");
+ return result.toString();
+ } else {
+ return "</body>";
+ }
+ }
+
+ /**
+ * Builds the end html of the body.<p>
+ *
+ * @return the end html of the body
+ */
+ public String bodyEnd() {
+ return pageBody(HTML_END, null, null);
+ }
+
+ /**
+ * Builds the end html of the page.<p>
+ *
+ * @return the end html of the page
+ */
+ public String htmlEnd() {
+ return pageHtml(HTML_END, null);
+ }
+
+ /**
+ * Returns the default html for a workplace page, including setting of DOCTYPE and
+ * inserting a header with the content-type.<p>
+ *
+ * @param segment the HTML segment (START / END)
+ * @param title the title of the page, if null no title tag is inserted
+ * @return the default html for a workplace page
+ */
+ public String pageHtml(int segment, String title) {
+ return pageHtmlStyle(segment, title, null);
+ }
+
+ /**
+ * Returns the default html for a workplace page, including setting of DOCTYPE and
+ * inserting a header with the content-type, allowing the selection of an individual style sheet.<p>
+ *
+ * @param segment the HTML segment (START / END)
+ * @param title the title of the page, if null no title tag is inserted
+ * @param stylesheet the used style sheet, if null the default stylesheet 'workplace.css' is inserted
+ * @return the default html for a workplace page
+ */
+ public String pageHtmlStyle(int segment, String title, String stylesheet) {
+ if (segment == HTML_START) {
+ StringBuffer result = new StringBuffer(512);
+// result.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n");
+// result.append("<html>\n<head>\n");
+// if (title != null) {
+// result.append("<title>");
+// result.append(title);
+// result.append("</title>\n");
+// }
+// result.append("<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n");
+ result.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
+ result.append("/pricat/includes/pricat.css");
+ result.append("\">\n");
+ return result.toString();
+ } else {
+ return "";
+// return "</html>";
+ }
+ }
+
+ /**
+ * Returns the start html for the outer dialog window border.
+ *
+ * @return the start html for the outer dialog window border
+ */
+ public String dialogStart() {
+ return dialog(HTML_START, null);
+ }
+
+ /**
+ * Builds the outer dialog window border.
+ *
+ * @param segment the HTML segment (START / END)
+ * @param attributes optional additional attributes for the opening dialog table
+ *
+ * @return a dialog window start / end segment
+ */
+ public String dialog(int segment, String attributes) {
+ if (segment == HTML_START) {
+ StringBuffer html = new StringBuffer(512);
+ html.append("<table class=\"dialog\" cellpadding=\"0\" cellspacing=\"0\"");
+ if (attributes != null) {
+ html.append(" ");
+ html.append(attributes);
+ }
+ html.append("><tr><td>\n<table class=\"dialogbox\" cellpadding=\"0\" cellspacing=\"0\">\n");
+ html.append("<tr><td>\n");
+ return html.toString();
+ } else {
+ return "</td></tr></table>\n</td></tr></table>\n<p> </p>\n";
+ }
+ }
+
+ /**
+ * Returns the start html for the content area of the dialog window.<p>
+ *
+ * @param title the title for the dialog
+ *
+ * @return the start html for the content area of the dialog window
+ */
+ public String dialogContentStart(String title) {
+ return dialogContent(HTML_START, title);
+ }
+
+ /**
+ * Builds the content area of the dialog window.<p>
+ *
+ * @param segment the HTML segment (START / END)
+ * @param title the title String for the dialog window
+ *
+ * @return a content area start / end segment
+ */
+ public String dialogContent(int segment, String title) {
+ if (segment == HTML_START) {
+ StringBuffer result = new StringBuffer(512);
+ // null title is ok, we always want the title headline
+ result.append(dialogHead(title));
+ result.append("<div class=\"dialogcontent\" unselectable=\"on\">\n");
+ result.append("<!-- dialogcontent start -->\n");
+ return result.toString();
+ } else {
+ return "<!-- dialogcontent end -->\n</div>\n";
+ }
+ }
+
+ /**
+ * Builds the title of the dialog window.<p>
+ *
+ * @param title the title String for the dialog window
+ *
+ * @return the HTML title String for the dialog window
+ */
+ public String dialogHead(String title) {
+ return "<div class=\"dialoghead\" unselectable=\"on\">" + (title == null ? "" : title) + "</div>";
+ }
+
+ /**
+ * Returns the value of the title parameter,
+ * or null if this parameter was not provided.<p>
+ *
+ * This parameter is used to build the title
+ * of the dialog. It is a parameter so that the title
+ * can be passed to included elements.<p>
+ *
+ * @return the value of the title parameter
+ */
+ public String getParamTitle(HttpServletRequest request) {
+ if (paramTitle == null) {
+ paramTitle = request.getParameter("title");
+ }
+ return paramTitle != null ? paramTitle : "";
+ }
+
+ /**
+ * Returns all initialized parameters of the current workplace class
+ * as hidden field tags that can be inserted in a form.<p>
+ *
+ * @return all initialized parameters of the current workplace class
+ * as hidden field tags that can be inserted in a html form
+ */
+ public String paramsAsHidden(HttpServletRequest request) {
+ return paramsAsHidden(request, null);
+ }
+
+ /**
+ * Returns all initialized parameters of the current workplace class
+ * that are not in the given exclusion list as hidden field tags that can be inserted in a form.<p>
+ *
+ * @param excludes the parameters to exclude
+ *
+ * @return all initialized parameters of the current workplace class
+ * that are not in the given exclusion list as hidden field tags that can be inserted in a form
+ */
+ public String paramsAsHidden(HttpServletRequest request, Collection<?> excludes) {
+ StringBuffer result = new StringBuffer(512);
+ Map<String, Object> params = paramValues(request);
+ Iterator<?> i = params.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry)i.next();
+ String param = (String)entry.getKey();
+ if ((excludes == null) || (!excludes.contains(param))) {
+ result.append("<input type=\"hidden\" name=\"");
+ result.append(param);
+ result.append("\" value=\"");
+ String encoded = ReportEncoder.encode(
+ entry.getValue().toString(),
+ "UTF-8");
+ result.append(encoded);
+ result.append("\">\n");
+ }
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Returns the values of all parameter methods of this workplace class instance.<p>
+ *
+ * @return the values of all parameter methods of this workplace class instance
+ */
+ protected Map<String, Object> paramValues(HttpServletRequest request) {
+ List<Method> methods = paramGetMethods();
+ Map<String, Object> map = new HashMap<String, Object>(methods.size());
+ Iterator<Method> i = methods.iterator();
+ while (i.hasNext()) {
+ Method m = (Method)i.next();
+ Object o = null;
+ try {
+ o = m.invoke(this, new Object[0]);
+ } catch (InvocationTargetException ite) {
+ // can usually be ignored
+ } catch (IllegalAccessException eae) {
+ // can usually be ignored
+ }
+ if (o != null) {
+ map.put(m.getName().substring(8).toLowerCase(), o);
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Returns a list of all methods of the current class instance that
+ * start with "getParam" and have no parameters.<p>
+ *
+ * @return a list of all methods of the current class instance that
+ * start with "getParam" and have no parameters
+ */
+ private List<Method> paramGetMethods() {
+ List<Method> list = new ArrayList<Method>();
+ Method[] methods = this.getClass().getMethods();
+ int length = methods.length;
+ for (int i = 0; i < length; i++) {
+ Method method = methods[i];
+ if (method.getName().startsWith("getParam") && (method.getParameterTypes().length == 0)) {
+ // Debug.logInfo("getMethod: " + method.getName(), module);
+ list.add(method);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns an optional introduction text to be displayed above the report output.<p>
+ *
+ * @return an optional introduction text
+ */
+ public String reportIntroductionText() {
+ return "";
+ }
+
+ /**
+ * Returns an optional conclusion text to be displayed below the report output.<p>
+ *
+ * @return an optional conclusion text
+ */
+ public String reportConclusionText() {
+ return "";
+ }
+
+ /**
+ * Returns the end html for the content area of the dialog window.<p>
+ *
+ * @return the end html for the content area of the dialog window
+ */
+ public String dialogContentEnd() {
+ return dialogContent(HTML_END, null);
+ }
+
+ /**
+ * Builds a button row with an "Ok" and a "Cancel" button.<p>
+ *
+ * This row is displayed when the first report is running.<p>
+ *
+ * @param okAttrs optional attributes for the ok button
+ * @param cancelAttrs optional attributes for the cancel button
+ * @return the button row
+ */
+ public String dialogButtonsContinue(String okAttrs, String cancelAttrs) {
+ return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[] {
+ okAttrs,
+ cancelAttrs});
+ }
+
+ /**
+ * Builds a button row with an "OK" and a "Cancel" button.<p>
+ *
+ * This row is used when a single report is running or after the first report has finished.<p>
+ *
+ * @param okAttrs optional attributes for the ok button
+ * @param cancelAttrs optional attributes for the cancel button
+ * @return the button row
+ */
+ public String dialogButtonsOkCancel(HttpServletRequest request, String okAttrs, String cancelAttrs) {
+ if (Boolean.valueOf(getParamThreadHasNext(request)).booleanValue()
+ && ReportStringUtil.isNotEmpty(getParamReportContinueKey())) {
+ return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL}, new String[] {
+ okAttrs,
+ cancelAttrs});
+ }
+ return dialogButtons(new int[] {BUTTON_OK}, new String[] {okAttrs});
+ }
+
+ /**
+ * Builds a button row with an "OK", a "Cancel" and a "Download" button.<p>
+ *
+ * This row is used when a single report is running or after the first report has finished.<p>
+ *
+ * @param okAttrs optional attributes for the ok button
+ * @param cancelAttrs optional attributes for the cancel button
+ * @param downloadAttrs optional attributes for the download button
+ * @return the button row
+ */
+ public String dialogButtonsOkCancelDownload(HttpServletRequest request, String okAttrs, String cancelAttrs, String downloadAttrs) {
+ if (ReportStringUtil.isEmptyOrWhitespaceOnly(downloadAttrs)) {
+ downloadAttrs = "";
+ } else {
+ downloadAttrs += " ";
+ }
+ if (Boolean.valueOf(getParamThreadHasNext(request)).booleanValue()
+ && ReportStringUtil.isNotEmpty(getParamReportContinueKey())) {
+ return dialogButtons(new int[] {BUTTON_OK, BUTTON_CANCEL, BUTTON_DOWNLOAD}, new String[] {
+ okAttrs,
+ cancelAttrs,
+ downloadAttrs + "onclick=\"downloadPricat(" + (sequenceNum > 0 ? sequenceNum : "") + ");\""});
+ }
+ return dialogButtons(new int[] {BUTTON_OK, BUTTON_DOWNLOAD}, new String[] {
+ okAttrs,
+ downloadAttrs + "onclick=\"downloadPricat(" + (sequenceNum > 0 ? sequenceNum : "") + ");\""});
+ }
+
+ /**
+ * Builds the html for the button row under the dialog content area, including buttons.<p>
+ *
+ * @param buttons array of constants of which buttons to include in the row
+ * @param attributes array of Strings for additional button attributes
+ *
+ * @return the html for the button row under the dialog content area, including buttons
+ */
+ public String dialogButtons(int[] buttons, String[] attributes) {
+ StringBuffer result = new StringBuffer(256);
+ result.append(dialogButtonRow(HTML_START));
+ for (int i = 0; i < buttons.length; i++) {
+ dialogButtonsHtml(result, buttons[i], attributes[i]);
+ }
+ result.append(dialogButtonRow(HTML_END));
+ return result.toString();
+ }
+
+ /**
+ * Builds the button row under the dialog content area without the buttons.<p>
+ *
+ * @param segment the HTML segment (START / END)
+ *
+ * @return the button row start / end segment
+ */
+ public String dialogButtonRow(int segment) {
+ if (segment == HTML_START) {
+ return "<!-- button row start -->\n<div class=\"dialogbuttons\" unselectable=\"on\">\n";
+ } else {
+ return "</div>\n<!-- button row end -->\n";
+ }
+ }
+
+ /**
+ * Renders the HTML for a single input button of a specified type.<p>
+ *
+ * @param result a string buffer where the rendered HTML gets appended to
+ * @param button a integer key to identify the button
+ * @param attribute an optional string with possible tag attributes, or null
+ */
+ protected void dialogButtonsHtml(StringBuffer result, int button, String attribute) {
+ attribute = appendDelimiter(attribute);
+ switch (button) {
+ case BUTTON_OK:
+ result.append("<input name=\"ok\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_OK", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" type=\"submit\"");
+ } else {
+ result.append(" type=\"button\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_CANCEL:
+ result.append("<input name=\"cancel\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_CANCEL", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_EDIT:
+ result.append("<input name=\"ok\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_EDIT", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" type=\"submit\"");
+ } else {
+ result.append(" type=\"button\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_DISCARD:
+ result.append("<input name=\"cancel\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_DISCARD", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_CLOSE:
+ result.append("<input name=\"close\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_CLOSE", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" onclick=\"submitAction('" + DIALOG_CANCEL + "', form);\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_ADVANCED:
+ result.append("<input name=\"advanced\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_ADVANCE", getLocale()) + "\"");
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_SET:
+ result.append("<input name=\"set\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_SET", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" onclick=\"submitAction('" + DIALOG_SET + "', form);\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_BACK:
+ result.append("<input name=\"set\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_BACK", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" onclick=\"submitAction('" + DIALOG_BACK + "', form);\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_CONTINUE:
+ result.append("<input name=\"set\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_CONTINUE", getLocale()) + "\"");
+ if (attribute.toLowerCase().indexOf("onclick") == -1) {
+ result.append(" onclick=\"submitAction('" + DIALOG_CONTINUE + "', form);\"");
+ }
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_DETAILS:
+ result.append("<input name=\"details\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_DETAIL", getLocale()) + "\"");
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ case BUTTON_DOWNLOAD:
+ result.append("<input name=\"download\" type=\"button\" value=\"");
+ result.append(UtilProperties.getMessage(resource, "DIALOG_BUTTON_DOWNLOAD", getLocale()) + "\"");
+ result.append(" class=\"dialogbutton\"");
+ result.append(attribute);
+ result.append(">\n");
+ break;
+ default:
+ // not a valid button code, just insert a warning in the HTML
+ result.append("<!-- invalid button code: ");
+ result.append(button);
+ result.append(" -->\n");
+ }
+ }
+
+ /**
+ * Appends a space char. between tag attributes.<p>
+ *
+ * @param attribute a tag attribute
+ *
+ * @return the tag attribute with a leading space char
+ */
+ protected String appendDelimiter(String attribute) {
+ if (ReportStringUtil.isNotEmpty(attribute)) {
+ if (!attribute.startsWith(" ")) {
+ // add a delimiter space between the beginning button HTML and the button tag attributes
+ return " " + attribute;
+ } else {
+ return attribute;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Returns true if the dialog operation has to be performed on multiple resources.<p>
+ *
+ * @return true if the dialog operation has to be performed on multiple resources, otherwise false
+ */
+ public boolean isMultiOperation(HttpServletRequest request) {
+ return (getResourceList(request).size() > 1);
+ }
+
+ /**
+ * Returns the resources that are defined for the dialog operation.
+ *
+ * For single resource operations, the list contains one item: the resource name found
+ * in the request parameter value of the "resource" parameter.
+ *
+ * @return the resources that are defined for the dialog operation
+ */
+ public List<String> getResourceList(HttpServletRequest request) {
+ if (resourceList == null) {
+ // use lazy initializing
+ if (getParamResourcelist(request) != null) {
+ // found the resourcelist parameter
+ resourceList = StringUtil.split(getParamResourcelist(request), DELIMITER_RESOURCES);
+ Collections.sort(resourceList);
+ } else {
+ // this is a single resource operation, create list containing the resource name
+ resourceList = new ArrayList<String>(1);
+ String resource = getParamResource(request);
+ if (ReportStringUtil.isNotEmptyOrWhitespaceOnly(resource)) {
+ resourceList.add(resource);
+ } else {
+ resourceList.add("");
+ }
+ }
+ }
+ return resourceList;
+ }
+
+ /**
+ * Returns the value of the resource list parameter, or null if the parameter is not provided.<p>
+ *
+ * This parameter selects the resources to perform operations on.<p>
+ *
+ * @return the value of the resource list parameter or null, if the parameter is not provided
+ */
+ public String getParamResourcelist(HttpServletRequest request) {
+ if (ReportStringUtil.isNotEmpty(paramResourcelist) && !"null".equals(paramResourcelist)) {
+ return paramResourcelist;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value of the file parameter,
+ * or null if this parameter was not provided.<p>
+ *
+ * The file parameter selects the file on which the dialog action
+ * is to be performed.<p>
+ *
+ * @return the value of the file parameter
+ */
+ public String getParamResource(HttpServletRequest request) {
+ paramResource = request.getParameter("resource");
+ if ((paramResource != null) && !"null".equals(paramResource)) {
+ return paramResource;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns if the workplace must be refreshed.<p>
+ *
+ * @return <code>"true"</code> if the workplace must be refreshed.
+ */
+ public String getParamRefreshWorkplace() {
+ return paramRefreshWorkplace;
+ }
+
+ /**
+ * Returns the key name which contains the localized message for the continue checkbox.<p>
+ *
+ * @return the key name which contains the localized message for the continue checkbox
+ */
+ public String getParamReportContinueKey() {
+ if (paramReportContinueKey == null) {
+ paramReportContinueKey = "";
+ }
+ return paramReportContinueKey;
+ }
+
+ /**
+ * Returns the value of the resourcelist parameter in form of a String separated
+ * with {@link #DELIMITER_RESOURCES}, or the value of the resource parameter if the
+ * first parameter is not provided (no multiple choice has been done.<p>
+ *
+ * This may be used for jsps as value for the parameter for resources {@link #PARAM_RESOURCELIST}.<p>
+ *
+ * @return the value of the resourcelist parameter or null, if the parameter is not provided
+ */
+ public String getResourceListAsParam(HttpServletRequest request) {
+ String result = getParamResourcelist(request);
+ if (ReportStringUtil.isEmptyOrWhitespaceOnly(result)) {
+ result = getParamResource(request);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the end html for the outer dialog window border.<p>
+ *
+ * @return the end html for the outer dialog window border
+ */
+ public String dialogEnd() {
+ return dialog(HTML_END, null);
+ }
+
+ /**
+ * Returns the http URI of the current dialog, to be used
+ * as value for the "action" attribute of a html form.<p>
+ *
+ * This URI is the real one.<p>
+ *
+ * @return the http URI of the current dialog
+ */
+ public String getDialogRealUri(HttpServletRequest request) {
+ return String.valueOf(request.getAttribute(DIALOG_URI));
+ }
+
+ /**
+ * Set the report form uri.
+ *
+ * @param request
+ * @param formUri
+ */
+ public void setFormRealUri(HttpServletRequest request, String formUri) {
+ request.setAttribute(FORM_URI, formUri);
+ }
+
+ /**
+ * Get the report form uri.
+ *
+ * @param request
+ * @return
+ */
+ public String getFormRealUri(HttpServletRequest request) {
+ return (String) request.getAttribute(FORM_URI);
+ }
+
+ public void addLogFile(String logFileName) {
+ if (logFile == null || logFileOutputStream == null) {
+ this.logFileName = logFileName;
+ logFile = FileUtil.getFile(logFileName);
+ try {
+ logFileOutputStream = new FileOutputStream(logFile);
+ } catch (FileNotFoundException e) {
+ // do nothing
+ }
+ }
+ }
+
+ public String closeLogFile() {
+ if (logFileOutputStream != null) {
+ try {
+ logFileOutputStream.flush();
+ } catch (IOException e) {
+ // do nothing
+ } finally {
+ if (logFileOutputStream != null) {
+ try {
+ logFileOutputStream.close();
+ } catch (IOException e) {
+ // do nothing
+ Debug.logError(e, HtmlReport.module);
+ }
+ }
+ }
+ }
+ return logFileName;
+ }
+
+ public String getLogFileName() {
+ return logFileName;
+ }
+
+ public long getSequenceNum() {
+ return sequenceNum;
+ }
+
+ public void setSequenceNum(long sequenceNum) {
+ this.sequenceNum = sequenceNum;
+ }
+}
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReport.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReport.java
index 931ee50..4146278 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReport.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReport.java
@@ -1,230 +1,230 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport;
-
-import java.util.List;
-import java.util.Locale;
-
-/**
- * This is the interface for the report classes which are used for the output
- * during operations that run on a separate Thread in OFBiz,
- * like import, export etc.<p>
- *
- */
-public interface InterfaceReport {
-
- /** Indicates default formatting. */
- int FORMAT_DEFAULT = 0;
-
- /** Indicates error formatting. */
- int FORMAT_ERROR = 5;
-
- /** Indicates headline formatting. */
- int FORMAT_HEADLINE = 2;
-
- /** Indicates note formatting. */
- int FORMAT_NOTE = 3;
-
- /** Indicates OK formatting. */
- int FORMAT_OK = 4;
-
- /** Indicates warning formatting. */
- int FORMAT_WARNING = 1;
-
- /** Request parameter value that this report should create an "extended" output. */
- String REPORT_TYPE_EXTENDED = "extended";
-
- /** Request parameter value that this report should create a "simple" output. */
- String REPORT_TYPE_SIMPLE = "simple";
-
- /**
- * Adds an error object to the list of errors that occured during the report.<p>
- *
- * @param obj the error object
- */
- void addError(Object obj);
-
- /**
- * Adds a warning object to the list of warnings that occured during the report.<p>
- *
- * @param obj the error object
- */
- void addWarning(Object obj);
-
- /**
- * Formats the runtime formatted as "hh:mm:ss".<p>
- *
- * @return the runtime formatted as "hh:mm:ss"
- */
- String formatRuntime();
-
- /**
- * Returns a list of all errors that occured during the report.<p>
- *
- * @return an error list that occured during the report
- */
- List<Object> getErrors();
-
- /**
- * Returns the locale this report was initialized with.<p>
- *
- * @return the locale this report was initialized with
- */
- Locale getLocale();
-
- /**
- * Updates this report, this processes all new output added since
- * the last call to this method.<p>
- *
- * This is only required in case the output is written to a HTML page,
- * if the shell output is used, this will just return an empty String.<p>
- *
- * @return new elements that have been added to the report and not yet processed.
- */
- String getReportUpdate();
-
- /**
- * Returns the time this report has been running.<p>
- *
- * @return the time this report has been running
- */
- long getRuntime();
-
- /**
- * Returns a list of all warnings that occured during the report.<p>
- *
- * @return a warning list that occured during the report
- */
- List<Object> getWarnings();
-
- /**
- * Returns if the report generated an error output.<p>
- *
- * @return true if the report generated an error, otherwise false
- */
- boolean hasError();
-
- /**
- * Returns if the report generated a warning output.<p>
- *
- * @return true if the report generated a warning, otherwise false
- */
- boolean hasWarning();
-
- /**
- * Prints a localized message to the report.<p>
- *
- * @param uiLabel the String to add
- */
- void print(String uiLabel);
-
- /**
- * Prints a localized message to the report, using the indicated formatting.<p>
- *
- * Use the contants starting with <code>FORMAT</code> from this interface
- * to indicate which formatting to use.<p>
- *
- * @param uiLabel the String to add
- * @param format the formatting to use for the output
- */
- void print(String uiLabel, int format);
-
- /**
- * Adds a line break to the report.<p>
- */
- void println();
-
- /**
- * Prints a localized message to the report.<p>
- *
- * @param uiLabel the message to add
- */
- void println(String uiLabel);
-
- /**
- * Prints a localized message to the report, using the indicated formatting.<p>
- *
- * Use the contents starting with <code>FORMAT</code> from this interface
- * to indicate which formatting to use.
- *
- * @param uiLabel the message container to add
- * @param format the formatting to use for the output
- */
- void println(String uiLabel, int format);
-
- /**
- * Adds an Exception to the report, ensuring that the Exception content is
- * processed to generate a valid output esp. for HTML pages.<p>
- *
- * The exception will be stored and the output will later be processed
- * in a special way.<p>
- *
- * @param t the exception to add
- *
- */
- void println(Throwable t);
-
- /**
- * Prints a localized message followed by a parameter and dots to the report.<p>
- *
- * @param uiLabel the Message to add
- * @param param the Parameter to add
- */
- void printMessageWithParam(String uiLabel, Object param);
-
- /**
- * Convenience method to print a localized message, followed by a parameter and dots to the report.<p>
- *
- * The output follows the pattern: ( 3 / 8 ) Deleting filename.txt ...
- *
- * @param m the number of the report output
- * @param n the total number of report outputs
- * @param uiLabel the Message to add
- * @param param the Parameter to add
- *
- */
- void printMessageWithParam(int m, int n, String uiLabel, Object param);
-
- /**
- * Resets the runtime to 0 milliseconds.<p>
- */
- void resetRuntime();
-
- /**
- * Add a log file to the report.
- *
- * @param logFileName
- */
- void addLogFile(String logFileName);
-
- /**
- * Close log file if necessary.
- *
- */
- String closeLogFile();
-
- /**
- * Set log's sequence number.
- * @param sequenceNum
- */
- void setSequenceNum(long sequenceNum);
-
- long getSequenceNum();
-
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport;
+
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * This is the interface for the report classes which are used for the output
+ * during operations that run on a separate Thread in OFBiz,
+ * like import, export etc.<p>
+ *
+ */
+public interface InterfaceReport {
+
+ /** Indicates default formatting. */
+ int FORMAT_DEFAULT = 0;
+
+ /** Indicates error formatting. */
+ int FORMAT_ERROR = 5;
+
+ /** Indicates headline formatting. */
+ int FORMAT_HEADLINE = 2;
+
+ /** Indicates note formatting. */
+ int FORMAT_NOTE = 3;
+
+ /** Indicates OK formatting. */
+ int FORMAT_OK = 4;
+
+ /** Indicates warning formatting. */
+ int FORMAT_WARNING = 1;
+
+ /** Request parameter value that this report should create an "extended" output. */
+ String REPORT_TYPE_EXTENDED = "extended";
+
+ /** Request parameter value that this report should create a "simple" output. */
+ String REPORT_TYPE_SIMPLE = "simple";
+
+ /**
+ * Adds an error object to the list of errors that occured during the report.<p>
+ *
+ * @param obj the error object
+ */
+ void addError(Object obj);
+
+ /**
+ * Adds a warning object to the list of warnings that occured during the report.<p>
+ *
+ * @param obj the error object
+ */
+ void addWarning(Object obj);
+
+ /**
+ * Formats the runtime formatted as "hh:mm:ss".<p>
+ *
+ * @return the runtime formatted as "hh:mm:ss"
+ */
+ String formatRuntime();
+
+ /**
+ * Returns a list of all errors that occured during the report.<p>
+ *
+ * @return an error list that occured during the report
+ */
+ List<Object> getErrors();
+
+ /**
+ * Returns the locale this report was initialized with.<p>
+ *
+ * @return the locale this report was initialized with
+ */
+ Locale getLocale();
+
+ /**
+ * Updates this report, this processes all new output added since
+ * the last call to this method.<p>
+ *
+ * This is only required in case the output is written to a HTML page,
+ * if the shell output is used, this will just return an empty String.<p>
+ *
+ * @return new elements that have been added to the report and not yet processed.
+ */
+ String getReportUpdate();
+
+ /**
+ * Returns the time this report has been running.<p>
+ *
+ * @return the time this report has been running
+ */
+ long getRuntime();
+
+ /**
+ * Returns a list of all warnings that occured during the report.<p>
+ *
+ * @return a warning list that occured during the report
+ */
+ List<Object> getWarnings();
+
+ /**
+ * Returns if the report generated an error output.<p>
+ *
+ * @return true if the report generated an error, otherwise false
+ */
+ boolean hasError();
+
+ /**
+ * Returns if the report generated a warning output.<p>
+ *
+ * @return true if the report generated a warning, otherwise false
+ */
+ boolean hasWarning();
+
+ /**
+ * Prints a localized message to the report.<p>
+ *
+ * @param uiLabel the String to add
+ */
+ void print(String uiLabel);
+
+ /**
+ * Prints a localized message to the report, using the indicated formatting.<p>
+ *
+ * Use the contants starting with <code>FORMAT</code> from this interface
+ * to indicate which formatting to use.<p>
+ *
+ * @param uiLabel the String to add
+ * @param format the formatting to use for the output
+ */
+ void print(String uiLabel, int format);
+
+ /**
+ * Adds a line break to the report.<p>
+ */
+ void println();
+
+ /**
+ * Prints a localized message to the report.<p>
+ *
+ * @param uiLabel the message to add
+ */
+ void println(String uiLabel);
+
+ /**
+ * Prints a localized message to the report, using the indicated formatting.<p>
+ *
+ * Use the contents starting with <code>FORMAT</code> from this interface
+ * to indicate which formatting to use.
+ *
+ * @param uiLabel the message container to add
+ * @param format the formatting to use for the output
+ */
+ void println(String uiLabel, int format);
+
+ /**
+ * Adds an Exception to the report, ensuring that the Exception content is
+ * processed to generate a valid output esp. for HTML pages.<p>
+ *
+ * The exception will be stored and the output will later be processed
+ * in a special way.<p>
+ *
+ * @param t the exception to add
+ *
+ */
+ void println(Throwable t);
+
+ /**
+ * Prints a localized message followed by a parameter and dots to the report.<p>
+ *
+ * @param uiLabel the Message to add
+ * @param param the Parameter to add
+ */
+ void printMessageWithParam(String uiLabel, Object param);
+
+ /**
+ * Convenience method to print a localized message, followed by a parameter and dots to the report.<p>
+ *
+ * The output follows the pattern: ( 3 / 8 ) Deleting filename.txt ...
+ *
+ * @param m the number of the report output
+ * @param n the total number of report outputs
+ * @param uiLabel the Message to add
+ * @param param the Parameter to add
+ *
+ */
+ void printMessageWithParam(int m, int n, String uiLabel, Object param);
+
+ /**
+ * Resets the runtime to 0 milliseconds.<p>
+ */
+ void resetRuntime();
+
+ /**
+ * Add a log file to the report.
+ *
+ * @param logFileName
+ */
+ void addLogFile(String logFileName);
+
+ /**
+ * Close log file if necessary.
+ *
+ */
+ String closeLogFile();
+
+ /**
+ * Set log's sequence number.
+ * @param sequenceNum
+ */
+ void setSequenceNum(long sequenceNum);
+
+ long getSequenceNum();
+
}
\ No newline at end of file
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReportThread.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReportThread.java
index 78e46df..344ef11 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReportThread.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/InterfaceReportThread.java
@@ -1,41 +1,41 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport;
-
-import org.safehaus.uuid.UUID;
-
-/**
- * Identifies a class that can be used as a report thread.
- *
- */
-public interface InterfaceReportThread {
-
- /**
- * Starts the report thread.<p>
- */
- void start();
-
- /**
- * Returns the UUID of this report thread.<p>
- *
- * @return the UUID of this report thread
- */
- UUID getUUID();
-
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport;
+
+import org.safehaus.uuid.UUID;
+
+/**
+ * Identifies a class that can be used as a report thread.
+ *
+ */
+public interface InterfaceReportThread {
+
+ /**
+ * Starts the report thread.<p>
+ */
+ void start();
+
+ /**
+ * Returns the UUID of this report thread.<p>
+ *
+ * @return the UUID of this report thread
+ */
+ UUID getUUID();
+
+}
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportEncoder.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportEncoder.java
index e787742..d82d3d0 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportEncoder.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportEncoder.java
@@ -1,678 +1,678 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport.util;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The ReportEncoder class provides static methods to decode and encode data.<p>
- *
- * The methods in this class are substitutes for <code>java.net.URLEncoder.encode()</code> and
- * <code>java.net.URLDecoder.decode()</code>.<p>
- *
- * The de- and encoding uses the same coding mechanism as JavaScript, special characters are
- * replaced with <code>%hex</code> where hex is a two digit hex number.<p>
- *
- * <b>Note:</b> On the client side (browser) instead of using corresponding <code>escape</code>
- * and <code>unescape</code> JavaScript functions, better use <code>encodeURIComponent</code> and
- * <code>decodeURIComponent</code> functions which are work properly with unicode characters.
- * These functions are supported in IE 5.5+ and NS 6+ only.<p>
- *
- */
-public final class ReportEncoder {
-
- /** Constant for the standard <code>ISO-8859-1</code> encoding. */
- public static final String ENCODING_ISO_8859_1 = "ISO-8859-1";
-
- /** Constant for the standard <code>US-ASCII</code> encoding. */
- public static final String ENCODING_US_ASCII = "US-ASCII";
-
- /**
- * Constant for the standard <code>UTF-8</code> encoding.<p>
- *
- * Default encoding for JavaScript decodeUriComponent methods is <code>UTF-8</code> by w3c standard.
- */
- public static final String ENCODING_UTF_8 = "UTF-8";
-
- /** The regex pattern to match HTML entities. */
- private static final Pattern ENTITIY_PATTERN = Pattern.compile("\\&#\\d+;");
-
- /** The prefix for HTML entities. */
- private static final String ENTITY_PREFIX = "&#";
-
- /** The replacement for HTML entity prefix in parameters. */
- private static final String ENTITY_REPLACEMENT = "$$";
-
- /** A cache for encoding name lookup. */
- private static Map<String, String> encodingCache = new HashMap<String, String>(16);
-
- /** The plus entity. */
- private static final String PLUS_ENTITY = ENTITY_PREFIX + "043;";
-
- /**
- * Constructor.<p>
- */
- private ReportEncoder() {
- // empty
- }
-
- /**
- * Adjusts the given String by making sure all characters that can be displayed
- * in the given charset are contained as chars, whereas all other non-displayable
- * characters are converted to HTML entities.<p>
- *
- * Just calls {@link #decodeHtmlEntities(String, String)} first and feeds the result
- * to {@link #encodeHtmlEntities(String, String)}. <p>
- *
- * @param input the input to adjust the HTML encoding for
- * @param encoding the charset to encode the result with\
- *
- * @return the input with the decoded/encoded HTML entities
- */
- public static String adjustHtmlEncoding(String input, String encoding) {
-
- return encodeHtmlEntities(decodeHtmlEntities(input, encoding), encoding);
- }
-
- /**
- * Changes the encoding of a byte array that represents a String.<p>
- *
- * @param input the byte array to convert
- * @param oldEncoding the current encoding of the byte array
- * @param newEncoding the new encoding of the byte array
- *
- * @return the byte array encoded in the new encoding
- */
- public static byte[] changeEncoding(byte[] input, String oldEncoding, String newEncoding) {
-
- if ((oldEncoding == null) || (newEncoding == null)) {
- return input;
- }
- if (oldEncoding.trim().equalsIgnoreCase(newEncoding.trim())) {
- return input;
- }
- byte[] result = input;
- try {
- result = (new String(input, oldEncoding)).getBytes(newEncoding);
- } catch (UnsupportedEncodingException e) {
- // return value will be input value
- }
- return result;
- }
-
- /**
- * Creates a String out of a byte array with the specified encoding, falling back
- * to the system default in case the encoding name is not valid.<p>
- *
- * Use this method as a replacement for <code>new String(byte[], encoding)</code>
- * to avoid possible encoding problems.<p>
- *
- * @param bytes the bytes to decode
- * @param encoding the encoding scheme to use for decoding the bytes
- *
- * @return the bytes decoded to a String
- */
- public static String createString(byte[] bytes, String encoding) {
-
- String enc = encoding.intern();
- if (enc != ENCODING_UTF_8) {
- enc = lookupEncoding(enc, null);
- }
- if (enc != null) {
- try {
- return new String(bytes, enc);
- } catch (UnsupportedEncodingException e) {
- // this can _never_ happen since the charset was looked up first
- }
- } else {
- enc = ENCODING_UTF_8;
- try {
- return new String(bytes, enc);
- } catch (UnsupportedEncodingException e) {
- // this can also _never_ happen since the default encoding is always valid
- }
- }
- // this code is unreachable in practice
- return null;
- }
-
- /**
- * Decodes a String using UTF-8 encoding, which is the standard for http data transmission
- * with GET ant POST requests.<p>
- *
- * @param source the String to decode
- *
- * @return String the decoded source String
- */
- public static String decode(String source) {
-
- return decode(source, ENCODING_UTF_8);
- }
-
- /**
- * This method is a substitute for <code>URLDecoder.decode()</code>.<p>
- *
- * In case you don't know what encoding to use, set the value of
- * the <code>encoding</code> parameter to <code>null</code>.
- * This method will then default to UTF-8 encoding, which is probably the right one.<p>
- *
- * @param source The string to decode
- * @param encoding The encoding to use (if null, the system default is used)
- *
- * @return The decoded source String
- */
- public static String decode(String source, String encoding) {
-
- if (source == null) {
- return null;
- }
- if (encoding != null) {
- try {
- return URLDecoder.decode(source, encoding);
- } catch (java.io.UnsupportedEncodingException e) {
- // will fallback to default
- }
- }
- // fallback to default decoding
- try {
- return URLDecoder.decode(source, ENCODING_UTF_8);
- } catch (java.io.UnsupportedEncodingException e) {
- // ignore
- }
- return source;
- }
-
- /**
- * Decodes HTML entity references like <code>&#8364;</code> that are contained in the
- * String to a regular character, but only if that character is contained in the given
- * encodings charset.<p>
- *
- * @param input the input to decode the HTML entities in
- * @param encoding the charset to decode the input for
- * @return the input with the decoded HTML entities
- *
- * @see #encodeHtmlEntities(String, String)
- */
- public static String decodeHtmlEntities(String input, String encoding) {
-
- Matcher matcher = ENTITIY_PATTERN.matcher(input);
- StringBuffer result = new StringBuffer(input.length());
- Charset charset = Charset.forName(encoding);
- CharsetEncoder encoder = charset.newEncoder();
-
- while (matcher.find()) {
- String entity = matcher.group();
- String value = entity.substring(2, entity.length() - 1);
- int c = Integer.valueOf(value).intValue();
- if (c < 128) {
- // first 128 chars are contained in almost every charset
- entity = new String(new char[] {(char)c});
- // this is intended as performance improvement since
- // the canEncode() operation appears quite CPU heavy
- } else if (encoder.canEncode((char)c)) {
- // encoder can encode this char
- entity = new String(new char[] {(char)c});
- }
- matcher.appendReplacement(result, entity);
- }
- matcher.appendTail(result);
- return result.toString();
- }
-
- /**
- * Decodes a string used as parameter in an uri in a way independent of other encodings/decodings applied before.<p>
- *
- * @param input the encoded parameter string
- *
- * @return the decoded parameter string
- *
- * @see #encodeParameter(String)
- */
- public static String decodeParameter(String input) {
-
- String result = ReportStringUtil.substitute(input, ENTITY_REPLACEMENT, ENTITY_PREFIX);
- return ReportEncoder.decodeHtmlEntities(result, ENCODING_UTF_8);
- }
-
- /**
- * Encodes a String using UTF-8 encoding, which is the standard for http data transmission
- * with GET ant POST requests.<p>
- *
- * @param source the String to encode
- *
- * @return String the encoded source String
- */
- public static String encode(String source) {
-
- return encode(source, ENCODING_UTF_8);
- }
-
- /**
- * This method is a substitute for <code>URLEncoder.encode()</code>.<p>
- *
- * In case you don't know what encoding to use, set the value of
- * the <code>encoding</code> parameter to <code>null</code>.
- * This method will then default to UTF-8 encoding, which is probably the right one.<p>
- *
- * @param source the String to encode
- * @param encoding the encoding to use (if null, the system default is used)
- *
- * @return the encoded source String
- */
- public static String encode(String source, String encoding) {
-
- if (source == null) {
- return null;
- }
- if (encoding != null) {
- try {
- return URLEncoder.encode(source, encoding);
- } catch (java.io.UnsupportedEncodingException e) {
- // will fallback to default
- }
- }
- // fallback to default encoding
- try {
- return URLEncoder.encode(source, ENCODING_UTF_8);
- } catch (java.io.UnsupportedEncodingException e) {
- // ignore
- }
- return source;
- }
-
- /**
- * Encodes all characters that are contained in the String which can not displayed
- * in the given encodings charset with HTML entity references
- * like <code>&#8364;</code>.<p>
- *
- * This is required since a Java String is
- * internally always stored as Unicode, meaning it can contain almost every character, but
- * the HTML charset used might not support all such characters.<p>
- *
- * @param input the input to encode for HTML
- * @param encoding the charset to encode the result with
- *
- * @return the input with the encoded HTML entities
- *
- * @see #decodeHtmlEntities(String, String)
- */
- public static String encodeHtmlEntities(String input, String encoding) {
-
- StringBuffer result = new StringBuffer(input.length() * 2);
- CharBuffer buffer = CharBuffer.wrap(input.toCharArray());
- Charset charset = Charset.forName(encoding);
- CharsetEncoder encoder = charset.newEncoder();
- for (int i = 0; i < buffer.length(); i++) {
- int c = buffer.get(i);
- if (c < 128) {
- // first 128 chars are contained in almost every charset
- result.append((char)c);
- // this is intended as performance improvement since
- // the canEncode() operation appears quite CPU heavy
- } else if (encoder.canEncode((char)c)) {
- // encoder can encode this char
- result.append((char)c);
- } else {
- // append HTML entity reference
- result.append(ENTITY_PREFIX);
- result.append(c);
- result.append(";");
- }
- }
- return result.toString();
- }
-
- /**
- * Encodes all characters that are contained in the String which can not displayed
- * in the given encodings charset with Java escaping like <code>\u20ac</code>.<p>
- *
- * This can be used to escape values used in Java property files.<p>
- *
- * @param input the input to encode for Java
- * @param encoding the charset to encode the result with
- *
- * @return the input with the encoded Java entities
- */
- public static String encodeJavaEntities(String input, String encoding) {
-
- StringBuffer result = new StringBuffer(input.length() * 2);
- CharBuffer buffer = CharBuffer.wrap(input.toCharArray());
- Charset charset = Charset.forName(encoding);
- CharsetEncoder encoder = charset.newEncoder();
- for (int i = 0; i < buffer.length(); i++) {
- int c = buffer.get(i);
- if (c < 128) {
- // first 128 chars are contained in almost every charset
- result.append((char)c);
- // this is intended as performance improvement since
- // the canEncode() operation appears quite CPU heavy
- } else if (encoder.canEncode((char)c)) {
- // encoder can encode this char
- result.append((char)c);
- } else {
- // append Java entity reference
- result.append("\\u");
- String hex = Integer.toHexString(c);
- int pad = 4 - hex.length();
- for (int p = 0; p < pad; p++) {
- result.append('0');
- }
- result.append(hex);
- }
- }
- return result.toString();
- }
-
- /**
- * Encodes a string used as parameter in an uri in a way independent of other encodings/decodings applied later.<p>
- *
- * Used to ensure that GET parameters are not wrecked by wrong or incompatible configuration settings.
- * In order to ensure this, the String is first encoded with html entities for any character that cannot encoded
- * in US-ASCII; additionally, the plus sign is also encoded to avoid problems with the white-space replacer.
- * Finally, the entity prefix is replaced with characters not used as delimiters in urls.<p>
- *
- * @param input the parameter string
- *
- * @return the encoded parameter string
- */
- public static String encodeParameter(String input) {
-
- String result = ReportEncoder.encodeHtmlEntities(input, ReportEncoder.ENCODING_US_ASCII);
- result = ReportStringUtil.substitute(result, "+", PLUS_ENTITY);
- return ReportStringUtil.substitute(result, ENTITY_PREFIX, ENTITY_REPLACEMENT);
- }
-
- /**
- * Encodes a String in a way that is compatible with the JavaScript escape function.
- *
- * @param source The text to be encoded
- * @param encoding the encoding type
- *
- * @return The JavaScript escaped string
- */
- public static String escape(String source, String encoding) {
-
- // the blank is encoded into "+" not "%20" when using standard encode call
- return ReportStringUtil.substitute(encode(source, encoding), "+", "%20");
- }
-
- /**
- * Escapes special characters in a HTML-String with their number-based
- * entity representation, for example & becomes &#38;.<p>
- *
- * A character <code>num</code> is replaced if<br>
- * <code>((ch != 32) && ((ch > 122) || (ch < 48) || (ch == 60) || (ch == 62)))</code><p>
- *
- * @param source the String to escape
- *
- * @return String the escaped String
- *
- * @see #escapeXml(String)
- */
- public static String escapeHtml(String source) {
-
- int terminatorIndex;
- if (source == null) {
- return null;
- }
- StringBuffer result = new StringBuffer(source.length() * 2);
- for (int i = 0; i < source.length(); i++) {
- int ch = source.charAt(i);
- // avoid escaping already escaped characters
- if (ch == 38) {
- terminatorIndex = source.indexOf(";", i);
- if (terminatorIndex > 0) {
- if (source.substring(i + 1, terminatorIndex).matches("#[0-9]+|lt|gt|amp|quote")) {
- result.append(source.substring(i, terminatorIndex + 1));
- // Skip remaining chars up to (and including) ";"
- i = terminatorIndex;
- continue;
- }
- }
- }
- if ((ch != 32) && ((ch > 122) || (ch < 48) || (ch == 60) || (ch == 62))) {
- result.append(ENTITY_PREFIX);
- result.append(ch);
- result.append(";");
- } else {
- result.append((char)ch);
- }
- }
- return new String(result);
- }
-
- /**
- * Escapes non ASCII characters in a HTML-String with their number-based
- * entity representation, for example & becomes &#38;.<p>
- *
- * A character <code>num</code> is replaced if<br>
- * <code>(ch > 255)</code><p>
- *
- * @param source the String to escape
- *
- * @return String the escaped String
- *
- * @see #escapeXml(String)
- */
- public static String escapeNonAscii(String source) {
-
- if (source == null) {
- return null;
- }
- StringBuffer result = new StringBuffer(source.length() * 2);
- for (int i = 0; i < source.length(); i++) {
- int ch = source.charAt(i);
- if (ch > 255) {
- result.append(ENTITY_PREFIX);
- result.append(ch);
- result.append(";");
- } else {
- result.append((char)ch);
- }
- }
- return new String(result);
- }
-
- /**
- * Encodes a String in a way that is compatible with the JavaScript escape function.
- * Multiple blanks are encoded _multiply _with <code>%20</code>.<p>
- *
- * @param source The text to be encoded
- * @param encoding the encoding type
- *
- * @return The JavaScript escaped string
- */
- public static String escapeWBlanks(String source, String encoding) {
-
- if (ReportStringUtil.isEmpty(source)) {
- return source;
- }
- StringBuffer ret = new StringBuffer(source.length() * 2);
-
- // URLEncode the text string
- // this produces a very similar encoding to JavaSscript encoding,
- // except the blank which is not encoded into "%20" instead of "+"
-
- String enc = encode(source, encoding);
- for (int z = 0; z < enc.length(); z++) {
- char c = enc.charAt(z);
- if (c == '+') {
- ret.append("%20");
- } else {
- ret.append(c);
- }
- }
- return ret.toString();
- }
-
- /**
- * Escapes a String so it may be printed as text content or attribute
- * value in a HTML page or an XML file.<p>
- *
- * This method replaces the following characters in a String:
- * <ul>
- * <li><b><</b> with &lt;
- * <li><b>></b> with &gt;
- * <li><b>&</b> with &amp;
- * <li><b>"</b> with &quot;
- * </ul><p>
- *
- * @param source the string to escape
- *
- * @return the escaped string
- *
- * @see #escapeHtml(String)
- */
- public static String escapeXml(String source) {
-
- return escapeXml(source, false);
- }
-
- /**
- * Escapes a String so it may be printed as text content or attribute
- * value in a HTML page or an XML file.<p>
- *
- * This method replaces the following characters in a String:
- * <ul>
- * <li><b><</b> with &lt;
- * <li><b>></b> with &gt;
- * <li><b>&</b> with &amp;
- * <li><b>"</b> with &quot;
- * </ul><p>
- *
- * @param source the string to escape
- * @param doubleEscape if <code>false</code>, all entities that already are escaped are left untouched
- *
- * @return the escaped string
- *
- * @see #escapeHtml(String)
- */
- public static String escapeXml(String source, boolean doubleEscape) {
-
- if (source == null) {
- return null;
- }
- StringBuffer result = new StringBuffer(source.length() * 2);
-
- for (int i = 0; i < source.length(); ++i) {
- char ch = source.charAt(i);
- switch (ch) {
- case '<':
- result.append("<");
- break;
- case '>':
- result.append(">");
- break;
- case '&':
- // don't escape already escaped international and special characters
- if (!doubleEscape) {
- int terminatorIndex = source.indexOf(";", i);
- if (terminatorIndex > 0) {
- if (source.substring(i + 1, terminatorIndex).matches("#[0-9]+")) {
- result.append(ch);
- break;
- }
- }
- }
- // note that to other "break" in the above "if" block
- result.append("&");
- break;
- case '"':
- result.append(""");
- break;
- default:
- result.append(ch);
- }
- }
- return new String(result);
- }
-
- /**
- * Checks if a given encoding name is actually supported, and if so
- * resolves it to it's canonical name, if not it returns the given fallback
- * value.<p>
- *
- * Charsets have a set of aliases. For example, valid aliases for "UTF-8"
- * are "UTF8", "utf-8" or "utf8". This method resolves any given valid charset name
- * to it's "canonical" form, so that simple String comparison can be used
- * when checking charset names internally later.<p>
- *
- * Please see <a href="http://www.iana.org/assignments/character-sets">http://www.iana.org/assignments/character-sets</a>
- * for a list of valid charset alias names.<p>
- *
- * @param encoding the encoding to check and resolve
- * @param fallback the fallback encoding scheme
- *
- * @return the resolved encoding name, or the fallback value
- */
- public static String lookupEncoding(String encoding, String fallback) {
-
- String result = (String) encodingCache.get(encoding);
- if (result != null) {
- return result;
- }
-
- try {
- result = Charset.forName(encoding).name();
- encodingCache.put(encoding, result);
- return result;
- } catch (Throwable t) {
- // we will use the default value as fallback
- }
-
- return fallback;
- }
-
- /**
- * Decodes a String in a way that is compatible with the JavaScript
- * unescape function.<p>
- *
- * @param source The String to be decoded
- * @param encoding the encoding type
- *
- * @return The JavaScript unescaped String
- */
- public static String unescape(String source, String encoding) {
-
- if (source == null) {
- return null;
- }
- int len = source.length();
- // to use standard decoder we need to replace '+' with "%20" (space)
- StringBuffer preparedSource = new StringBuffer(len);
- for (int i = 0; i < len; i++) {
- char c = source.charAt(i);
- if (c == '+') {
- preparedSource.append("%20");
- } else {
- preparedSource.append(c);
- }
- }
- return decode(preparedSource.toString(), encoding);
- }
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The ReportEncoder class provides static methods to decode and encode data.<p>
+ *
+ * The methods in this class are substitutes for <code>java.net.URLEncoder.encode()</code> and
+ * <code>java.net.URLDecoder.decode()</code>.<p>
+ *
+ * The de- and encoding uses the same coding mechanism as JavaScript, special characters are
+ * replaced with <code>%hex</code> where hex is a two digit hex number.<p>
+ *
+ * <b>Note:</b> On the client side (browser) instead of using corresponding <code>escape</code>
+ * and <code>unescape</code> JavaScript functions, better use <code>encodeURIComponent</code> and
+ * <code>decodeURIComponent</code> functions which are work properly with unicode characters.
+ * These functions are supported in IE 5.5+ and NS 6+ only.<p>
+ *
+ */
+public final class ReportEncoder {
+
+ /** Constant for the standard <code>ISO-8859-1</code> encoding. */
+ public static final String ENCODING_ISO_8859_1 = "ISO-8859-1";
+
+ /** Constant for the standard <code>US-ASCII</code> encoding. */
+ public static final String ENCODING_US_ASCII = "US-ASCII";
+
+ /**
+ * Constant for the standard <code>UTF-8</code> encoding.<p>
+ *
+ * Default encoding for JavaScript decodeUriComponent methods is <code>UTF-8</code> by w3c standard.
+ */
+ public static final String ENCODING_UTF_8 = "UTF-8";
+
+ /** The regex pattern to match HTML entities. */
+ private static final Pattern ENTITIY_PATTERN = Pattern.compile("\\&#\\d+;");
+
+ /** The prefix for HTML entities. */
+ private static final String ENTITY_PREFIX = "&#";
+
+ /** The replacement for HTML entity prefix in parameters. */
+ private static final String ENTITY_REPLACEMENT = "$$";
+
+ /** A cache for encoding name lookup. */
+ private static Map<String, String> encodingCache = new HashMap<String, String>(16);
+
+ /** The plus entity. */
+ private static final String PLUS_ENTITY = ENTITY_PREFIX + "043;";
+
+ /**
+ * Constructor.<p>
+ */
+ private ReportEncoder() {
+ // empty
+ }
+
+ /**
+ * Adjusts the given String by making sure all characters that can be displayed
+ * in the given charset are contained as chars, whereas all other non-displayable
+ * characters are converted to HTML entities.<p>
+ *
+ * Just calls {@link #decodeHtmlEntities(String, String)} first and feeds the result
+ * to {@link #encodeHtmlEntities(String, String)}. <p>
+ *
+ * @param input the input to adjust the HTML encoding for
+ * @param encoding the charset to encode the result with\
+ *
+ * @return the input with the decoded/encoded HTML entities
+ */
+ public static String adjustHtmlEncoding(String input, String encoding) {
+
+ return encodeHtmlEntities(decodeHtmlEntities(input, encoding), encoding);
+ }
+
+ /**
+ * Changes the encoding of a byte array that represents a String.<p>
+ *
+ * @param input the byte array to convert
+ * @param oldEncoding the current encoding of the byte array
+ * @param newEncoding the new encoding of the byte array
+ *
+ * @return the byte array encoded in the new encoding
+ */
+ public static byte[] changeEncoding(byte[] input, String oldEncoding, String newEncoding) {
+
+ if ((oldEncoding == null) || (newEncoding == null)) {
+ return input;
+ }
+ if (oldEncoding.trim().equalsIgnoreCase(newEncoding.trim())) {
+ return input;
+ }
+ byte[] result = input;
+ try {
+ result = (new String(input, oldEncoding)).getBytes(newEncoding);
+ } catch (UnsupportedEncodingException e) {
+ // return value will be input value
+ }
+ return result;
+ }
+
+ /**
+ * Creates a String out of a byte array with the specified encoding, falling back
+ * to the system default in case the encoding name is not valid.<p>
+ *
+ * Use this method as a replacement for <code>new String(byte[], encoding)</code>
+ * to avoid possible encoding problems.<p>
+ *
+ * @param bytes the bytes to decode
+ * @param encoding the encoding scheme to use for decoding the bytes
+ *
+ * @return the bytes decoded to a String
+ */
+ public static String createString(byte[] bytes, String encoding) {
+
+ String enc = encoding.intern();
+ if (enc != ENCODING_UTF_8) {
+ enc = lookupEncoding(enc, null);
+ }
+ if (enc != null) {
+ try {
+ return new String(bytes, enc);
+ } catch (UnsupportedEncodingException e) {
+ // this can _never_ happen since the charset was looked up first
+ }
+ } else {
+ enc = ENCODING_UTF_8;
+ try {
+ return new String(bytes, enc);
+ } catch (UnsupportedEncodingException e) {
+ // this can also _never_ happen since the default encoding is always valid
+ }
+ }
+ // this code is unreachable in practice
+ return null;
+ }
+
+ /**
+ * Decodes a String using UTF-8 encoding, which is the standard for http data transmission
+ * with GET ant POST requests.<p>
+ *
+ * @param source the String to decode
+ *
+ * @return String the decoded source String
+ */
+ public static String decode(String source) {
+
+ return decode(source, ENCODING_UTF_8);
+ }
+
+ /**
+ * This method is a substitute for <code>URLDecoder.decode()</code>.<p>
+ *
+ * In case you don't know what encoding to use, set the value of
+ * the <code>encoding</code> parameter to <code>null</code>.
+ * This method will then default to UTF-8 encoding, which is probably the right one.<p>
+ *
+ * @param source The string to decode
+ * @param encoding The encoding to use (if null, the system default is used)
+ *
+ * @return The decoded source String
+ */
+ public static String decode(String source, String encoding) {
+
+ if (source == null) {
+ return null;
+ }
+ if (encoding != null) {
+ try {
+ return URLDecoder.decode(source, encoding);
+ } catch (java.io.UnsupportedEncodingException e) {
+ // will fallback to default
+ }
+ }
+ // fallback to default decoding
+ try {
+ return URLDecoder.decode(source, ENCODING_UTF_8);
+ } catch (java.io.UnsupportedEncodingException e) {
+ // ignore
+ }
+ return source;
+ }
+
+ /**
+ * Decodes HTML entity references like <code>&#8364;</code> that are contained in the
+ * String to a regular character, but only if that character is contained in the given
+ * encodings charset.<p>
+ *
+ * @param input the input to decode the HTML entities in
+ * @param encoding the charset to decode the input for
+ * @return the input with the decoded HTML entities
+ *
+ * @see #encodeHtmlEntities(String, String)
+ */
+ public static String decodeHtmlEntities(String input, String encoding) {
+
+ Matcher matcher = ENTITIY_PATTERN.matcher(input);
+ StringBuffer result = new StringBuffer(input.length());
+ Charset charset = Charset.forName(encoding);
+ CharsetEncoder encoder = charset.newEncoder();
+
+ while (matcher.find()) {
+ String entity = matcher.group();
+ String value = entity.substring(2, entity.length() - 1);
+ int c = Integer.valueOf(value).intValue();
+ if (c < 128) {
+ // first 128 chars are contained in almost every charset
+ entity = new String(new char[] {(char)c});
+ // this is intended as performance improvement since
+ // the canEncode() operation appears quite CPU heavy
+ } else if (encoder.canEncode((char)c)) {
+ // encoder can encode this char
+ entity = new String(new char[] {(char)c});
+ }
+ matcher.appendReplacement(result, entity);
+ }
+ matcher.appendTail(result);
+ return result.toString();
+ }
+
+ /**
+ * Decodes a string used as parameter in an uri in a way independent of other encodings/decodings applied before.<p>
+ *
+ * @param input the encoded parameter string
+ *
+ * @return the decoded parameter string
+ *
+ * @see #encodeParameter(String)
+ */
+ public static String decodeParameter(String input) {
+
+ String result = ReportStringUtil.substitute(input, ENTITY_REPLACEMENT, ENTITY_PREFIX);
+ return ReportEncoder.decodeHtmlEntities(result, ENCODING_UTF_8);
+ }
+
+ /**
+ * Encodes a String using UTF-8 encoding, which is the standard for http data transmission
+ * with GET ant POST requests.<p>
+ *
+ * @param source the String to encode
+ *
+ * @return String the encoded source String
+ */
+ public static String encode(String source) {
+
+ return encode(source, ENCODING_UTF_8);
+ }
+
+ /**
+ * This method is a substitute for <code>URLEncoder.encode()</code>.<p>
+ *
+ * In case you don't know what encoding to use, set the value of
+ * the <code>encoding</code> parameter to <code>null</code>.
+ * This method will then default to UTF-8 encoding, which is probably the right one.<p>
+ *
+ * @param source the String to encode
+ * @param encoding the encoding to use (if null, the system default is used)
+ *
+ * @return the encoded source String
+ */
+ public static String encode(String source, String encoding) {
+
+ if (source == null) {
+ return null;
+ }
+ if (encoding != null) {
+ try {
+ return URLEncoder.encode(source, encoding);
+ } catch (java.io.UnsupportedEncodingException e) {
+ // will fallback to default
+ }
+ }
+ // fallback to default encoding
+ try {
+ return URLEncoder.encode(source, ENCODING_UTF_8);
+ } catch (java.io.UnsupportedEncodingException e) {
+ // ignore
+ }
+ return source;
+ }
+
+ /**
+ * Encodes all characters that are contained in the String which can not displayed
+ * in the given encodings charset with HTML entity references
+ * like <code>&#8364;</code>.<p>
+ *
+ * This is required since a Java String is
+ * internally always stored as Unicode, meaning it can contain almost every character, but
+ * the HTML charset used might not support all such characters.<p>
+ *
+ * @param input the input to encode for HTML
+ * @param encoding the charset to encode the result with
+ *
+ * @return the input with the encoded HTML entities
+ *
+ * @see #decodeHtmlEntities(String, String)
+ */
+ public static String encodeHtmlEntities(String input, String encoding) {
+
+ StringBuffer result = new StringBuffer(input.length() * 2);
+ CharBuffer buffer = CharBuffer.wrap(input.toCharArray());
+ Charset charset = Charset.forName(encoding);
+ CharsetEncoder encoder = charset.newEncoder();
+ for (int i = 0; i < buffer.length(); i++) {
+ int c = buffer.get(i);
+ if (c < 128) {
+ // first 128 chars are contained in almost every charset
+ result.append((char)c);
+ // this is intended as performance improvement since
+ // the canEncode() operation appears quite CPU heavy
+ } else if (encoder.canEncode((char)c)) {
+ // encoder can encode this char
+ result.append((char)c);
+ } else {
+ // append HTML entity reference
+ result.append(ENTITY_PREFIX);
+ result.append(c);
+ result.append(";");
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Encodes all characters that are contained in the String which can not displayed
+ * in the given encodings charset with Java escaping like <code>\u20ac</code>.<p>
+ *
+ * This can be used to escape values used in Java property files.<p>
+ *
+ * @param input the input to encode for Java
+ * @param encoding the charset to encode the result with
+ *
+ * @return the input with the encoded Java entities
+ */
+ public static String encodeJavaEntities(String input, String encoding) {
+
+ StringBuffer result = new StringBuffer(input.length() * 2);
+ CharBuffer buffer = CharBuffer.wrap(input.toCharArray());
+ Charset charset = Charset.forName(encoding);
+ CharsetEncoder encoder = charset.newEncoder();
+ for (int i = 0; i < buffer.length(); i++) {
+ int c = buffer.get(i);
+ if (c < 128) {
+ // first 128 chars are contained in almost every charset
+ result.append((char)c);
+ // this is intended as performance improvement since
+ // the canEncode() operation appears quite CPU heavy
+ } else if (encoder.canEncode((char)c)) {
+ // encoder can encode this char
+ result.append((char)c);
+ } else {
+ // append Java entity reference
+ result.append("\\u");
+ String hex = Integer.toHexString(c);
+ int pad = 4 - hex.length();
+ for (int p = 0; p < pad; p++) {
+ result.append('0');
+ }
+ result.append(hex);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Encodes a string used as parameter in an uri in a way independent of other encodings/decodings applied later.<p>
+ *
+ * Used to ensure that GET parameters are not wrecked by wrong or incompatible configuration settings.
+ * In order to ensure this, the String is first encoded with html entities for any character that cannot encoded
+ * in US-ASCII; additionally, the plus sign is also encoded to avoid problems with the white-space replacer.
+ * Finally, the entity prefix is replaced with characters not used as delimiters in urls.<p>
+ *
+ * @param input the parameter string
+ *
+ * @return the encoded parameter string
+ */
+ public static String encodeParameter(String input) {
+
+ String result = ReportEncoder.encodeHtmlEntities(input, ReportEncoder.ENCODING_US_ASCII);
+ result = ReportStringUtil.substitute(result, "+", PLUS_ENTITY);
+ return ReportStringUtil.substitute(result, ENTITY_PREFIX, ENTITY_REPLACEMENT);
+ }
+
+ /**
+ * Encodes a String in a way that is compatible with the JavaScript escape function.
+ *
+ * @param source The text to be encoded
+ * @param encoding the encoding type
+ *
+ * @return The JavaScript escaped string
+ */
+ public static String escape(String source, String encoding) {
+
+ // the blank is encoded into "+" not "%20" when using standard encode call
+ return ReportStringUtil.substitute(encode(source, encoding), "+", "%20");
+ }
+
+ /**
+ * Escapes special characters in a HTML-String with their number-based
+ * entity representation, for example & becomes &#38;.<p>
+ *
+ * A character <code>num</code> is replaced if<br>
+ * <code>((ch != 32) && ((ch > 122) || (ch < 48) || (ch == 60) || (ch == 62)))</code><p>
+ *
+ * @param source the String to escape
+ *
+ * @return String the escaped String
+ *
+ * @see #escapeXml(String)
+ */
+ public static String escapeHtml(String source) {
+
+ int terminatorIndex;
+ if (source == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer(source.length() * 2);
+ for (int i = 0; i < source.length(); i++) {
+ int ch = source.charAt(i);
+ // avoid escaping already escaped characters
+ if (ch == 38) {
+ terminatorIndex = source.indexOf(";", i);
+ if (terminatorIndex > 0) {
+ if (source.substring(i + 1, terminatorIndex).matches("#[0-9]+|lt|gt|amp|quote")) {
+ result.append(source.substring(i, terminatorIndex + 1));
+ // Skip remaining chars up to (and including) ";"
+ i = terminatorIndex;
+ continue;
+ }
+ }
+ }
+ if ((ch != 32) && ((ch > 122) || (ch < 48) || (ch == 60) || (ch == 62))) {
+ result.append(ENTITY_PREFIX);
+ result.append(ch);
+ result.append(";");
+ } else {
+ result.append((char)ch);
+ }
+ }
+ return new String(result);
+ }
+
+ /**
+ * Escapes non ASCII characters in a HTML-String with their number-based
+ * entity representation, for example & becomes &#38;.<p>
+ *
+ * A character <code>num</code> is replaced if<br>
+ * <code>(ch > 255)</code><p>
+ *
+ * @param source the String to escape
+ *
+ * @return String the escaped String
+ *
+ * @see #escapeXml(String)
+ */
+ public static String escapeNonAscii(String source) {
+
+ if (source == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer(source.length() * 2);
+ for (int i = 0; i < source.length(); i++) {
+ int ch = source.charAt(i);
+ if (ch > 255) {
+ result.append(ENTITY_PREFIX);
+ result.append(ch);
+ result.append(";");
+ } else {
+ result.append((char)ch);
+ }
+ }
+ return new String(result);
+ }
+
+ /**
+ * Encodes a String in a way that is compatible with the JavaScript escape function.
+ * Multiple blanks are encoded _multiply _with <code>%20</code>.<p>
+ *
+ * @param source The text to be encoded
+ * @param encoding the encoding type
+ *
+ * @return The JavaScript escaped string
+ */
+ public static String escapeWBlanks(String source, String encoding) {
+
+ if (ReportStringUtil.isEmpty(source)) {
+ return source;
+ }
+ StringBuffer ret = new StringBuffer(source.length() * 2);
+
+ // URLEncode the text string
+ // this produces a very similar encoding to JavaSscript encoding,
+ // except the blank which is not encoded into "%20" instead of "+"
+
+ String enc = encode(source, encoding);
+ for (int z = 0; z < enc.length(); z++) {
+ char c = enc.charAt(z);
+ if (c == '+') {
+ ret.append("%20");
+ } else {
+ ret.append(c);
+ }
+ }
+ return ret.toString();
+ }
+
+ /**
+ * Escapes a String so it may be printed as text content or attribute
+ * value in a HTML page or an XML file.<p>
+ *
+ * This method replaces the following characters in a String:
+ * <ul>
+ * <li><b><</b> with &lt;
+ * <li><b>></b> with &gt;
+ * <li><b>&</b> with &amp;
+ * <li><b>"</b> with &quot;
+ * </ul><p>
+ *
+ * @param source the string to escape
+ *
+ * @return the escaped string
+ *
+ * @see #escapeHtml(String)
+ */
+ public static String escapeXml(String source) {
+
+ return escapeXml(source, false);
+ }
+
+ /**
+ * Escapes a String so it may be printed as text content or attribute
+ * value in a HTML page or an XML file.<p>
+ *
+ * This method replaces the following characters in a String:
+ * <ul>
+ * <li><b><</b> with &lt;
+ * <li><b>></b> with &gt;
+ * <li><b>&</b> with &amp;
+ * <li><b>"</b> with &quot;
+ * </ul><p>
+ *
+ * @param source the string to escape
+ * @param doubleEscape if <code>false</code>, all entities that already are escaped are left untouched
+ *
+ * @return the escaped string
+ *
+ * @see #escapeHtml(String)
+ */
+ public static String escapeXml(String source, boolean doubleEscape) {
+
+ if (source == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer(source.length() * 2);
+
+ for (int i = 0; i < source.length(); ++i) {
+ char ch = source.charAt(i);
+ switch (ch) {
+ case '<':
+ result.append("<");
+ break;
+ case '>':
+ result.append(">");
+ break;
+ case '&':
+ // don't escape already escaped international and special characters
+ if (!doubleEscape) {
+ int terminatorIndex = source.indexOf(";", i);
+ if (terminatorIndex > 0) {
+ if (source.substring(i + 1, terminatorIndex).matches("#[0-9]+")) {
+ result.append(ch);
+ break;
+ }
+ }
+ }
+ // note that to other "break" in the above "if" block
+ result.append("&");
+ break;
+ case '"':
+ result.append(""");
+ break;
+ default:
+ result.append(ch);
+ }
+ }
+ return new String(result);
+ }
+
+ /**
+ * Checks if a given encoding name is actually supported, and if so
+ * resolves it to it's canonical name, if not it returns the given fallback
+ * value.<p>
+ *
+ * Charsets have a set of aliases. For example, valid aliases for "UTF-8"
+ * are "UTF8", "utf-8" or "utf8". This method resolves any given valid charset name
+ * to it's "canonical" form, so that simple String comparison can be used
+ * when checking charset names internally later.<p>
+ *
+ * Please see <a href="http://www.iana.org/assignments/character-sets">http://www.iana.org/assignments/character-sets</a>
+ * for a list of valid charset alias names.<p>
+ *
+ * @param encoding the encoding to check and resolve
+ * @param fallback the fallback encoding scheme
+ *
+ * @return the resolved encoding name, or the fallback value
+ */
+ public static String lookupEncoding(String encoding, String fallback) {
+
+ String result = (String) encodingCache.get(encoding);
+ if (result != null) {
+ return result;
+ }
+
+ try {
+ result = Charset.forName(encoding).name();
+ encodingCache.put(encoding, result);
+ return result;
+ } catch (Throwable t) {
+ // we will use the default value as fallback
+ }
+
+ return fallback;
+ }
+
+ /**
+ * Decodes a String in a way that is compatible with the JavaScript
+ * unescape function.<p>
+ *
+ * @param source The String to be decoded
+ * @param encoding the encoding type
+ *
+ * @return The JavaScript unescaped String
+ */
+ public static String unescape(String source, String encoding) {
+
+ if (source == null) {
+ return null;
+ }
+ int len = source.length();
+ // to use standard decoder we need to replace '+' with "%20" (space)
+ StringBuffer preparedSource = new StringBuffer(len);
+ for (int i = 0; i < len; i++) {
+ char c = source.charAt(i);
+ if (c == '+') {
+ preparedSource.append("%20");
+ } else {
+ preparedSource.append(c);
+ }
+ }
+ return decode(preparedSource.toString(), encoding);
+ }
}
\ No newline at end of file
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportStringUtil.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportStringUtil.java
index f1baa0b..fb2c1af 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportStringUtil.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/htmlreport/util/ReportStringUtil.java
@@ -1,570 +1,570 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.htmlreport.util;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * Provides String utility functions.<p>
- *
- */
-public final class ReportStringUtil {
-
- /** Constant for <code>"false"</code>. */
- public static final String FALSE = Boolean.toString(false);
-
- /** a convenient shorthand to the line separator constant. */
- public static final String LINE_SEPARATOR = System.getProperty("line.separator");
-
- /** Contains all chars that end a sentence in the {@link #trimToSize(String, int, int, String)} method. */
- public static final char[] SENTENCE_ENDING_CHARS = {'.', '!', '?'};
-
- /** a convenient shorthand for tabulations. */
- public static final String TABULATOR = " ";
-
- /** Constant for <code>"true"</code>. */
- public static final String TRUE = Boolean.toString(true);
-
- /** Day constant. */
- private static final long DAYS = 1000 * 60 * 60 * 24;
-
- /** Hour constant. */
- private static final long HOURS = 1000 * 60 * 60;
-
- /** Minute constant. */
- private static final long MINUTES = 1000 * 60;
-
- /** Second constant. */
- private static final long SECONDS = 1000;
-
- /**
- * Default constructor (empty), private because this class has only
- * static methods.<p>
- */
- private ReportStringUtil() {
- // empty
- }
-
- /**
- * Changes the filename suffix.
- *
- * @param filename the filename to be changed
- * @param suffix the new suffix of the file
- *
- * @return the filename with the replaced suffix
- */
- public static String changeFileNameSuffixTo(String filename, String suffix) {
-
- int dotPos = filename.lastIndexOf('.');
- if (dotPos != -1) {
- return filename.substring(0, dotPos + 1) + suffix;
- } else {
- // the string has no suffix
- return filename;
- }
- }
-
- /**
- * Returns a string representation for the given collection using the given separator.<p>
- *
- * @param collection the collection to print
- * @param separator the item separator
- *
- * @return the string representation for the given collection
- */
- public static String collectionAsString(Collection<String> collection, String separator) {
-
- StringBuffer string = new StringBuffer(128);
- Iterator<String> it = collection.iterator();
- while (it.hasNext()) {
- string.append(it.next());
- if (it.hasNext()) {
- string.append(separator);
- }
- }
- return string.toString();
- }
-
- /**
- * Replaces occurrences of special control characters in the given input with
- * a HTML representation.<p>
- *
- * This method currently replaces line breaks to <code><br/></code> and special HTML chars
- * like <code>< > & "</code> with their HTML entity representation.<p>
- *
- * @param source the String to escape
- *
- * @return the escaped String
- */
- public static String escapeHtml(String source) {
-
- if (source == null) {
- return null;
- }
- source = ReportEncoder.escapeXml(source);
- source = substitute(source, "\r", "");
- source = substitute(source, "\n", "<br/>\n");
- return source;
- }
-
- /**
- * Escapes a String so it may be used in JavaScript String definitions.<p>
- *
- * This method replaces line breaks, quotation marks and \ characters.<p>
- *
- * @param source the String to escape
- *
- * @return the escaped String
- */
- public static String escapeJavaScript(String source) {
-
- source = substitute(source, "\\", "\\\\");
- source = substitute(source, "\"", "\\\"");
- source = substitute(source, "\'", "\\\'");
- source = substitute(source, "\r\n", "\\n");
- source = substitute(source, "\n", "\\n");
- return source;
- }
-
- /**
- * Escapes a String so it may be used as a Perl5 regular expression.<p>
- *
- * This method replaces the following characters in a String:<br>
- * <code>{}[]()\$^.*+/</code><p>
- *
- * @param source the string to escape
- *
- * @return the escaped string
- */
- public static String escapePattern(String source) {
-
- if (source == null) {
- return null;
- }
- StringBuffer result = new StringBuffer(source.length() * 2);
- for (int i = 0; i < source.length(); ++i) {
- char ch = source.charAt(i);
- switch (ch) {
- case '\\':
- result.append("\\\\");
- break;
- case '/':
- result.append("\\/");
- break;
- case '$':
- result.append("\\$");
- break;
- case '^':
- result.append("\\^");
- break;
- case '.':
- result.append("\\.");
- break;
- case '*':
- result.append("\\*");
- break;
- case '+':
- result.append("\\+");
- break;
- case '|':
- result.append("\\|");
- break;
- case '?':
- result.append("\\?");
- break;
- case '{':
- result.append("\\{");
- break;
- case '}':
- result.append("\\}");
- break;
- case '[':
- result.append("\\[");
- break;
- case ']':
- result.append("\\]");
- break;
- case '(':
- result.append("\\(");
- break;
- case ')':
- result.append("\\)");
- break;
- default:
- result.append(ch);
- }
- }
- return new String(result);
- }
-
- /**
- * Formats a runtime in the format hh:mm:ss, to be used e.g. in reports.<p>
- *
- * If the runtime is greater then 24 hours, the format dd:hh:mm:ss is used.<p>
- *
- * @param runtime the time to format
- *
- * @return the formatted runtime
- */
- public static String formatRuntime(long runtime) {
-
- long seconds = (runtime / SECONDS) % 60;
- long minutes = (runtime / MINUTES) % 60;
- long hours = (runtime / HOURS) % 24;
- long days = runtime / DAYS;
- StringBuffer strBuf = new StringBuffer();
-
- if (days > 0) {
- if (days < 10) {
- strBuf.append('0');
- }
- strBuf.append(days);
- strBuf.append(':');
- }
-
- if (hours < 10) {
- strBuf.append('0');
- }
- strBuf.append(hours);
- strBuf.append(':');
-
- if (minutes < 10) {
- strBuf.append('0');
- }
- strBuf.append(minutes);
- strBuf.append(':');
-
- if (seconds < 10) {
- strBuf.append('0');
- }
- strBuf.append(seconds);
-
- return strBuf.toString();
- }
-
- /**
- * Returns <code>true</code> if the provided String is either <code>null</code>
- * or the empty String <code>""</code>.<p>
- *
- * @param value the value to check
- *
- * @return true, if the provided value is null or the empty String, false otherwise
- */
- public static boolean isEmpty(String value) {
-
- return (value == null) || (value.length() == 0);
- }
-
- /**
- * Returns <code>true</code> if the provided String is either <code>null</code>
- * or contains only white spaces.<p>
- *
- * @param value the value to check
- *
- * @return true, if the provided value is null or contains only white spaces, false otherwise
- */
- public static boolean isEmptyOrWhitespaceOnly(String value) {
-
- return isEmpty(value) || (value.trim().length() == 0);
- }
-
- /**
- * Returns <code>true</code> if the provided Objects are either both <code>null</code>
- * or equal according to {@link Object#equals(Object)}.<p>
- *
- * @param value1 the first object to compare
- * @param value2 the second object to compare
- *
- * @return <code>true</code> if the provided Objects are either both <code>null</code>
- * or equal according to {@link Object#equals(Object)}
- */
- public static boolean isEqual(Object value1, Object value2) {
-
- if (value1 == null) {
- return (value2 == null);
- }
- return value1.equals(value2);
- }
-
- /**
- * Returns <code>true</code> if the provided String is neither <code>null</code>
- * nor the empty String <code>""</code>.<p>
- *
- * @param value the value to check
- *
- * @return true, if the provided value is not null and not the empty String, false otherwise
- */
- public static boolean isNotEmpty(String value) {
-
- return (value != null) && (value.length() != 0);
- }
-
- /**
- * Returns <code>true</code> if the provided String is neither <code>null</code>
- * nor contains only white spaces.<p>
- *
- * @param value the value to check
- *
- * @return <code>true</code>, if the provided value is <code>null</code>
- * or contains only white spaces, <code>false</code> otherwise
- */
- public static boolean isNotEmptyOrWhitespaceOnly(String value) {
-
- return (value != null) && (value.trim().length() > 0);
- }
-
- /**
- * Returns the last index of any of the given chars in the given source.<p>
- *
- * If no char is found, -1 is returned.<p>
- *
- * @param source the source to check
- * @param chars the chars to find
- *
- * @return the last index of any of the given chars in the given source, or -1
- */
- public static int lastIndexOf(String source, char[] chars) {
-
- // now try to find an "sentence ending" char in the text in the "findPointArea"
- int result = -1;
- for (int i = 0; i < chars.length; i++) {
- int pos = source.lastIndexOf(chars[i]);
- if (pos > result) {
- // found new last char
- result = pos;
- }
- }
- return result;
- }
-
- /**
- * Returns the last index a whitespace char the given source.<p>
- *
- * If no whitespace char is found, -1 is returned.<p>
- *
- * @param source the source to check
- *
- * @return the last index a whitespace char the given source, or -1
- */
- public static int lastWhitespaceIn(String source) {
-
- if (isEmpty(source)) {
- return -1;
- }
- int pos = -1;
- for (int i = source.length() - 1; i >= 0; i--) {
- if (Character.isWhitespace(source.charAt(i))) {
- pos = i;
- break;
- }
- }
- return pos;
- }
-
- /**
- * Substitutes <code>searchString</code> in the given source String with <code>replaceString</code>.<p>
- *
- * This is a high-performance implementation which should be used as a replacement for
- * <code>{@link String#replaceAll(java.lang.String, java.lang.String)}</code> in case no
- * regular expression evaluation is required.<p>
- *
- * @param source the content which is scanned
- * @param searchString the String which is searched in content
- * @param replaceString the String which replaces <code>searchString</code>
- *
- * @return the substituted String
- */
- public static String substitute(String source, String searchString, String replaceString) {
-
- if (source == null) {
- return null;
- }
-
- if (isEmpty(searchString)) {
- return source;
- }
-
- if (replaceString == null) {
- replaceString = "";
- }
- int len = source.length();
- int sl = searchString.length();
- int rl = replaceString.length();
- int length;
- if (sl == rl) {
- length = len;
- } else {
- int c = 0;
- int s = 0;
- int e;
- while ((e = source.indexOf(searchString, s)) != -1) {
- c++;
- s = e + sl;
- }
- if (c == 0) {
- return source;
- }
- length = len - (c * (sl - rl));
- }
-
- int s = 0;
- int e = source.indexOf(searchString, s);
- if (e == -1) {
- return source;
- }
- StringBuffer sb = new StringBuffer(length);
- while (e != -1) {
- sb.append(source.substring(s, e));
- sb.append(replaceString);
- s = e + sl;
- e = source.indexOf(searchString, s);
- }
- e = len;
- sb.append(source.substring(s, e));
- return sb.toString();
- }
-
- /**
- * Returns the java String literal for the given String. <p>
- *
- * This is the form of the String that had to be written into source code
- * using the unicode escape sequence for special characters. <p>
- *
- * Example: "�" would be transformed to "\\u00C4".<p>
- *
- * @param s a string that may contain non-ascii characters
- *
- * @return the java unicode escaped string Literal of the given input string
- */
- public static String toUnicodeLiteral(String s) {
-
- StringBuffer result = new StringBuffer();
- char[] carr = s.toCharArray();
-
- String unicode;
- for (int i = 0; i < carr.length; i++) {
- result.append("\\u");
- // append leading zeros
- unicode = Integer.toHexString(carr[i]).toUpperCase();
- for (int j = 4 - unicode.length(); j > 0; j--) {
- result.append("0");
- }
- result.append(unicode);
- }
- return result.toString();
- }
-
- /**
- * Returns a substring of the source, which is at most length characters long.<p>
- *
- * This is the same as calling {@link #trimToSize(String, int, String)} with the
- * parameters <code>(source, length, " ...")</code>.<p>
- *
- * @param source the string to trim
- * @param length the maximum length of the string to be returned
- *
- * @return a substring of the source, which is at most length characters long
- */
- public static String trimToSize(String source, int length) {
-
- return trimToSize(source, length, length, " ...");
- }
-
- /**
- * Returns a substring of the source, which is at most length characters long.<p>
- *
- * If a char is cut, the given <code>suffix</code> is appended to the result.<p>
- *
- * This is almost the same as calling {@link #trimToSize(String, int, int, String)} with the
- * parameters <code>(source, length, length*, suffix)</code>. If <code>length</code>
- * if larger then 100, then <code>length* = length / 2</code>,
- * otherwise <code>length* = length</code>.<p>
- *
- * @param source the string to trim
- * @param length the maximum length of the string to be returned
- * @param suffix the suffix to append in case the String was trimmed
- *
- * @return a substring of the source, which is at most length characters long
- */
- public static String trimToSize(String source, int length, String suffix) {
-
- int area = (length > 100) ? length / 2 : length;
- return trimToSize(source, length, area, suffix);
- }
-
- /**
- * Returns a substring of the source, which is at most length characters long, cut
- * in the last <code>area</code> chars in the source at a sentence ending char or whitespace.<p>
- *
- * If a char is cut, the given <code>suffix</code> is appended to the result.<p>
- *
- * @param source the string to trim
- * @param length the maximum length of the string to be returned
- * @param area the area at the end of the string in which to find a sentence ender or whitespace
- * @param suffix the suffix to append in case the String was trimmed
- *
- * @return a substring of the source, which is at most length characters long
- */
- public static String trimToSize(String source, int length, int area, String suffix) {
-
- if ((source == null) || (source.length() <= length)) {
- // no operation is required
- return source;
- }
- if (isEmpty(suffix)) {
- // we need an empty suffix
- suffix = "";
- }
- // must remove the length from the after sequence chars since these are always added in the end
- int modLength = length - suffix.length();
- if (modLength <= 0) {
- // we are to short, return beginning of the suffix
- return suffix.substring(0, length);
- }
- int modArea = area + suffix.length();
- if ((modArea > modLength) || (modArea < 0)) {
- // area must not be longer then max length
- modArea = modLength;
- }
-
- // first reduce the String to the maximum allowed length
- String findPointSource = source.substring(modLength - modArea, modLength);
-
- String result;
- // try to find an "sentence ending" char in the text
- int pos = lastIndexOf(findPointSource, SENTENCE_ENDING_CHARS);
- if (pos >= 0) {
- // found a sentence ender in the lookup area, keep the sentence ender
- result = source.substring(0, modLength - modArea + pos + 1) + suffix;
- } else {
- // no sentence ender was found, try to find a whitespace
- pos = lastWhitespaceIn(findPointSource);
- if (pos >= 0) {
- // found a whitespace, don't keep the whitespace
- result = source.substring(0, modLength - modArea + pos) + suffix;
- } else {
- // not even a whitespace was found, just cut away what's to long
- result = source.substring(0, modLength) + suffix;
- }
- }
-
- return result;
- }
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.htmlreport.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * Provides String utility functions.<p>
+ *
+ */
+public final class ReportStringUtil {
+
+ /** Constant for <code>"false"</code>. */
+ public static final String FALSE = Boolean.toString(false);
+
+ /** a convenient shorthand to the line separator constant. */
+ public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ /** Contains all chars that end a sentence in the {@link #trimToSize(String, int, int, String)} method. */
+ public static final char[] SENTENCE_ENDING_CHARS = {'.', '!', '?'};
+
+ /** a convenient shorthand for tabulations. */
+ public static final String TABULATOR = " ";
+
+ /** Constant for <code>"true"</code>. */
+ public static final String TRUE = Boolean.toString(true);
+
+ /** Day constant. */
+ private static final long DAYS = 1000 * 60 * 60 * 24;
+
+ /** Hour constant. */
+ private static final long HOURS = 1000 * 60 * 60;
+
+ /** Minute constant. */
+ private static final long MINUTES = 1000 * 60;
+
+ /** Second constant. */
+ private static final long SECONDS = 1000;
+
+ /**
+ * Default constructor (empty), private because this class has only
+ * static methods.<p>
+ */
+ private ReportStringUtil() {
+ // empty
+ }
+
+ /**
+ * Changes the filename suffix.
+ *
+ * @param filename the filename to be changed
+ * @param suffix the new suffix of the file
+ *
+ * @return the filename with the replaced suffix
+ */
+ public static String changeFileNameSuffixTo(String filename, String suffix) {
+
+ int dotPos = filename.lastIndexOf('.');
+ if (dotPos != -1) {
+ return filename.substring(0, dotPos + 1) + suffix;
+ } else {
+ // the string has no suffix
+ return filename;
+ }
+ }
+
+ /**
+ * Returns a string representation for the given collection using the given separator.<p>
+ *
+ * @param collection the collection to print
+ * @param separator the item separator
+ *
+ * @return the string representation for the given collection
+ */
+ public static String collectionAsString(Collection<String> collection, String separator) {
+
+ StringBuffer string = new StringBuffer(128);
+ Iterator<String> it = collection.iterator();
+ while (it.hasNext()) {
+ string.append(it.next());
+ if (it.hasNext()) {
+ string.append(separator);
+ }
+ }
+ return string.toString();
+ }
+
+ /**
+ * Replaces occurrences of special control characters in the given input with
+ * a HTML representation.<p>
+ *
+ * This method currently replaces line breaks to <code><br/></code> and special HTML chars
+ * like <code>< > & "</code> with their HTML entity representation.<p>
+ *
+ * @param source the String to escape
+ *
+ * @return the escaped String
+ */
+ public static String escapeHtml(String source) {
+
+ if (source == null) {
+ return null;
+ }
+ source = ReportEncoder.escapeXml(source);
+ source = substitute(source, "\r", "");
+ source = substitute(source, "\n", "<br/>\n");
+ return source;
+ }
+
+ /**
+ * Escapes a String so it may be used in JavaScript String definitions.<p>
+ *
+ * This method replaces line breaks, quotation marks and \ characters.<p>
+ *
+ * @param source the String to escape
+ *
+ * @return the escaped String
+ */
+ public static String escapeJavaScript(String source) {
+
+ source = substitute(source, "\\", "\\\\");
+ source = substitute(source, "\"", "\\\"");
+ source = substitute(source, "\'", "\\\'");
+ source = substitute(source, "\r\n", "\\n");
+ source = substitute(source, "\n", "\\n");
+ return source;
+ }
+
+ /**
+ * Escapes a String so it may be used as a Perl5 regular expression.<p>
+ *
+ * This method replaces the following characters in a String:<br>
+ * <code>{}[]()\$^.*+/</code><p>
+ *
+ * @param source the string to escape
+ *
+ * @return the escaped string
+ */
+ public static String escapePattern(String source) {
+
+ if (source == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer(source.length() * 2);
+ for (int i = 0; i < source.length(); ++i) {
+ char ch = source.charAt(i);
+ switch (ch) {
+ case '\\':
+ result.append("\\\\");
+ break;
+ case '/':
+ result.append("\\/");
+ break;
+ case '$':
+ result.append("\\$");
+ break;
+ case '^':
+ result.append("\\^");
+ break;
+ case '.':
+ result.append("\\.");
+ break;
+ case '*':
+ result.append("\\*");
+ break;
+ case '+':
+ result.append("\\+");
+ break;
+ case '|':
+ result.append("\\|");
+ break;
+ case '?':
+ result.append("\\?");
+ break;
+ case '{':
+ result.append("\\{");
+ break;
+ case '}':
+ result.append("\\}");
+ break;
+ case '[':
+ result.append("\\[");
+ break;
+ case ']':
+ result.append("\\]");
+ break;
+ case '(':
+ result.append("\\(");
+ break;
+ case ')':
+ result.append("\\)");
+ break;
+ default:
+ result.append(ch);
+ }
+ }
+ return new String(result);
+ }
+
+ /**
+ * Formats a runtime in the format hh:mm:ss, to be used e.g. in reports.<p>
+ *
+ * If the runtime is greater then 24 hours, the format dd:hh:mm:ss is used.<p>
+ *
+ * @param runtime the time to format
+ *
+ * @return the formatted runtime
+ */
+ public static String formatRuntime(long runtime) {
+
+ long seconds = (runtime / SECONDS) % 60;
+ long minutes = (runtime / MINUTES) % 60;
+ long hours = (runtime / HOURS) % 24;
+ long days = runtime / DAYS;
+ StringBuffer strBuf = new StringBuffer();
+
+ if (days > 0) {
+ if (days < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(days);
+ strBuf.append(':');
+ }
+
+ if (hours < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(hours);
+ strBuf.append(':');
+
+ if (minutes < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(minutes);
+ strBuf.append(':');
+
+ if (seconds < 10) {
+ strBuf.append('0');
+ }
+ strBuf.append(seconds);
+
+ return strBuf.toString();
+ }
+
+ /**
+ * Returns <code>true</code> if the provided String is either <code>null</code>
+ * or the empty String <code>""</code>.<p>
+ *
+ * @param value the value to check
+ *
+ * @return true, if the provided value is null or the empty String, false otherwise
+ */
+ public static boolean isEmpty(String value) {
+
+ return (value == null) || (value.length() == 0);
+ }
+
+ /**
+ * Returns <code>true</code> if the provided String is either <code>null</code>
+ * or contains only white spaces.<p>
+ *
+ * @param value the value to check
+ *
+ * @return true, if the provided value is null or contains only white spaces, false otherwise
+ */
+ public static boolean isEmptyOrWhitespaceOnly(String value) {
+
+ return isEmpty(value) || (value.trim().length() == 0);
+ }
+
+ /**
+ * Returns <code>true</code> if the provided Objects are either both <code>null</code>
+ * or equal according to {@link Object#equals(Object)}.<p>
+ *
+ * @param value1 the first object to compare
+ * @param value2 the second object to compare
+ *
+ * @return <code>true</code> if the provided Objects are either both <code>null</code>
+ * or equal according to {@link Object#equals(Object)}
+ */
+ public static boolean isEqual(Object value1, Object value2) {
+
+ if (value1 == null) {
+ return (value2 == null);
+ }
+ return value1.equals(value2);
+ }
+
+ /**
+ * Returns <code>true</code> if the provided String is neither <code>null</code>
+ * nor the empty String <code>""</code>.<p>
+ *
+ * @param value the value to check
+ *
+ * @return true, if the provided value is not null and not the empty String, false otherwise
+ */
+ public static boolean isNotEmpty(String value) {
+
+ return (value != null) && (value.length() != 0);
+ }
+
+ /**
+ * Returns <code>true</code> if the provided String is neither <code>null</code>
+ * nor contains only white spaces.<p>
+ *
+ * @param value the value to check
+ *
+ * @return <code>true</code>, if the provided value is <code>null</code>
+ * or contains only white spaces, <code>false</code> otherwise
+ */
+ public static boolean isNotEmptyOrWhitespaceOnly(String value) {
+
+ return (value != null) && (value.trim().length() > 0);
+ }
+
+ /**
+ * Returns the last index of any of the given chars in the given source.<p>
+ *
+ * If no char is found, -1 is returned.<p>
+ *
+ * @param source the source to check
+ * @param chars the chars to find
+ *
+ * @return the last index of any of the given chars in the given source, or -1
+ */
+ public static int lastIndexOf(String source, char[] chars) {
+
+ // now try to find an "sentence ending" char in the text in the "findPointArea"
+ int result = -1;
+ for (int i = 0; i < chars.length; i++) {
+ int pos = source.lastIndexOf(chars[i]);
+ if (pos > result) {
+ // found new last char
+ result = pos;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the last index a whitespace char the given source.<p>
+ *
+ * If no whitespace char is found, -1 is returned.<p>
+ *
+ * @param source the source to check
+ *
+ * @return the last index a whitespace char the given source, or -1
+ */
+ public static int lastWhitespaceIn(String source) {
+
+ if (isEmpty(source)) {
+ return -1;
+ }
+ int pos = -1;
+ for (int i = source.length() - 1; i >= 0; i--) {
+ if (Character.isWhitespace(source.charAt(i))) {
+ pos = i;
+ break;
+ }
+ }
+ return pos;
+ }
+
+ /**
+ * Substitutes <code>searchString</code> in the given source String with <code>replaceString</code>.<p>
+ *
+ * This is a high-performance implementation which should be used as a replacement for
+ * <code>{@link String#replaceAll(java.lang.String, java.lang.String)}</code> in case no
+ * regular expression evaluation is required.<p>
+ *
+ * @param source the content which is scanned
+ * @param searchString the String which is searched in content
+ * @param replaceString the String which replaces <code>searchString</code>
+ *
+ * @return the substituted String
+ */
+ public static String substitute(String source, String searchString, String replaceString) {
+
+ if (source == null) {
+ return null;
+ }
+
+ if (isEmpty(searchString)) {
+ return source;
+ }
+
+ if (replaceString == null) {
+ replaceString = "";
+ }
+ int len = source.length();
+ int sl = searchString.length();
+ int rl = replaceString.length();
+ int length;
+ if (sl == rl) {
+ length = len;
+ } else {
+ int c = 0;
+ int s = 0;
+ int e;
+ while ((e = source.indexOf(searchString, s)) != -1) {
+ c++;
+ s = e + sl;
+ }
+ if (c == 0) {
+ return source;
+ }
+ length = len - (c * (sl - rl));
+ }
+
+ int s = 0;
+ int e = source.indexOf(searchString, s);
+ if (e == -1) {
+ return source;
+ }
+ StringBuffer sb = new StringBuffer(length);
+ while (e != -1) {
+ sb.append(source.substring(s, e));
+ sb.append(replaceString);
+ s = e + sl;
+ e = source.indexOf(searchString, s);
+ }
+ e = len;
+ sb.append(source.substring(s, e));
+ return sb.toString();
+ }
+
+ /**
+ * Returns the java String literal for the given String. <p>
+ *
+ * This is the form of the String that had to be written into source code
+ * using the unicode escape sequence for special characters. <p>
+ *
+ * Example: "�" would be transformed to "\\u00C4".<p>
+ *
+ * @param s a string that may contain non-ascii characters
+ *
+ * @return the java unicode escaped string Literal of the given input string
+ */
+ public static String toUnicodeLiteral(String s) {
+
+ StringBuffer result = new StringBuffer();
+ char[] carr = s.toCharArray();
+
+ String unicode;
+ for (int i = 0; i < carr.length; i++) {
+ result.append("\\u");
+ // append leading zeros
+ unicode = Integer.toHexString(carr[i]).toUpperCase();
+ for (int j = 4 - unicode.length(); j > 0; j--) {
+ result.append("0");
+ }
+ result.append(unicode);
+ }
+ return result.toString();
+ }
+
+ /**
+ * Returns a substring of the source, which is at most length characters long.<p>
+ *
+ * This is the same as calling {@link #trimToSize(String, int, String)} with the
+ * parameters <code>(source, length, " ...")</code>.<p>
+ *
+ * @param source the string to trim
+ * @param length the maximum length of the string to be returned
+ *
+ * @return a substring of the source, which is at most length characters long
+ */
+ public static String trimToSize(String source, int length) {
+
+ return trimToSize(source, length, length, " ...");
+ }
+
+ /**
+ * Returns a substring of the source, which is at most length characters long.<p>
+ *
+ * If a char is cut, the given <code>suffix</code> is appended to the result.<p>
+ *
+ * This is almost the same as calling {@link #trimToSize(String, int, int, String)} with the
+ * parameters <code>(source, length, length*, suffix)</code>. If <code>length</code>
+ * if larger then 100, then <code>length* = length / 2</code>,
+ * otherwise <code>length* = length</code>.<p>
+ *
+ * @param source the string to trim
+ * @param length the maximum length of the string to be returned
+ * @param suffix the suffix to append in case the String was trimmed
+ *
+ * @return a substring of the source, which is at most length characters long
+ */
+ public static String trimToSize(String source, int length, String suffix) {
+
+ int area = (length > 100) ? length / 2 : length;
+ return trimToSize(source, length, area, suffix);
+ }
+
+ /**
+ * Returns a substring of the source, which is at most length characters long, cut
+ * in the last <code>area</code> chars in the source at a sentence ending char or whitespace.<p>
+ *
+ * If a char is cut, the given <code>suffix</code> is appended to the result.<p>
+ *
+ * @param source the string to trim
+ * @param length the maximum length of the string to be returned
+ * @param area the area at the end of the string in which to find a sentence ender or whitespace
+ * @param suffix the suffix to append in case the String was trimmed
+ *
+ * @return a substring of the source, which is at most length characters long
+ */
+ public static String trimToSize(String source, int length, int area, String suffix) {
+
+ if ((source == null) || (source.length() <= length)) {
+ // no operation is required
+ return source;
+ }
+ if (isEmpty(suffix)) {
+ // we need an empty suffix
+ suffix = "";
+ }
+ // must remove the length from the after sequence chars since these are always added in the end
+ int modLength = length - suffix.length();
+ if (modLength <= 0) {
+ // we are to short, return beginning of the suffix
+ return suffix.substring(0, length);
+ }
+ int modArea = area + suffix.length();
+ if ((modArea > modLength) || (modArea < 0)) {
+ // area must not be longer then max length
+ modArea = modLength;
+ }
+
+ // first reduce the String to the maximum allowed length
+ String findPointSource = source.substring(modLength - modArea, modLength);
+
+ String result;
+ // try to find an "sentence ending" char in the text
+ int pos = lastIndexOf(findPointSource, SENTENCE_ENDING_CHARS);
+ if (pos >= 0) {
+ // found a sentence ender in the lookup area, keep the sentence ender
+ result = source.substring(0, modLength - modArea + pos + 1) + suffix;
+ } else {
+ // no sentence ender was found, try to find a whitespace
+ pos = lastWhitespaceIn(findPointSource);
+ if (pos >= 0) {
+ // found a whitespace, don't keep the whitespace
+ result = source.substring(0, modLength - modArea + pos) + suffix;
+ } else {
+ // not even a whitespace was found, just cut away what's to long
+ result = source.substring(0, modLength) + suffix;
+ }
+ }
+
+ return result;
+ }
}
\ No newline at end of file
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatEvents.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatEvents.java
index f1ad508..4b47931 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatEvents.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/PricatEvents.java
@@ -1,193 +1,193 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.pricat;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URLEncoder;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.jdom.JDOMException;
-import org.apache.ofbiz.base.location.ComponentLocationResolver;
-import org.apache.ofbiz.base.util.Debug;
-import org.apache.ofbiz.base.util.FileUtil;
-import org.apache.ofbiz.base.util.UtilHttp;
-import org.apache.ofbiz.base.util.UtilMisc;
-import org.apache.ofbiz.base.util.UtilProperties;
-import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.entity.Delegator;
-import org.apache.ofbiz.entity.GenericEntityException;
-import org.apache.ofbiz.entity.GenericValue;
-import org.apache.ofbiz.pricat.AbstractPricatParser;
-import org.apache.ofbiz.pricat.InterfacePricatParser;
-import org.apache.ofbiz.pricat.PricatParseExcelHtmlThread;
-
-public class PricatEvents {
-
- public static final String module = PricatEvents.class.getName();
-
- public static final String PricatLatestVersion = UtilProperties.getPropertyValue("pricat", "pricat.latest.version", "V1.1");
-
- public static final String PricatFileName = "PricatTemplate_" + PricatLatestVersion + ".xlsx";
-
- public static final String PricatPath = "component://pricat/webapp/pricat/downloads/";
-
- /**
- * Download excel template.
- *
- * @param request
- * @param response
- * @return
- * @throws IOException
- * @throws JDOMException
- */
- public static String downloadExcelTemplate(HttpServletRequest request, HttpServletResponse response) {
- String templateType = request.getParameter("templateType");
- if (UtilValidate.isEmpty(templateType)) {
- return "error";
- }
- try {
- String path = ComponentLocationResolver.getBaseLocation(PricatPath).toString();
- String fileName = null;
- if ("pricatExcelTemplate".equals(templateType)) {
- fileName = PricatFileName;
- }
- if (UtilValidate.isEmpty(fileName)) {
- return "error";
- }
- Path file = Paths.get(path + fileName);
- byte[] bytes = Files.readAllBytes(file);
- UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8"));
- } catch (MalformedURLException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- } catch (IOException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- }
- return "success";
- }
-
- /**
- * Upload a pricat.
- */
- public static String pricatUpload(HttpServletRequest request, HttpServletResponse response) {
- boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
- if (isMultiPart) {
- return "parse_pricat";
- } else {
- String action = request.getParameter("action");
- if (UtilValidate.isNotEmpty(action) && "downloadPricat".equals(action)) {
- String sequenceNumString = (String) request.getParameter("sequenceNum");
- long sequenceNum = -1;
- if (UtilValidate.isNotEmpty(sequenceNumString)) {
- try {
- sequenceNum = Long.valueOf(sequenceNumString);
- } catch (NumberFormatException e) {
- // do nothing
- }
- }
- String originalPricatFileName = (String) request.getSession().getAttribute(PricatParseExcelHtmlThread.PRICAT_FILE);
- String pricatFileName = originalPricatFileName;
- if (sequenceNum > 0 && AbstractPricatParser.isCommentedExcelExists(request, sequenceNum)) {
- GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");
- String userLoginId = userLogin.getString("userLoginId");
- pricatFileName = InterfacePricatParser.tempFilesFolder + userLoginId + "/" + sequenceNum + ".xlsx";
- }
- if (UtilValidate.isNotEmpty(pricatFileName) && UtilValidate.isNotEmpty(originalPricatFileName)) {
- try {
- Path path = Paths.get(pricatFileName);
- byte[] bytes = Files.readAllBytes(path);
- path = Paths.get(originalPricatFileName);
- UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(path.getName(path.getNameCount() - 1).toString(), "UTF-8"));
- } catch (MalformedURLException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- } catch (IOException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- }
- request.getSession().removeAttribute(PricatParseExcelHtmlThread.PRICAT_FILE);
- return "download";
- }
- }
- }
- return "success";
- }
-
- /**
- * Download commented excel file after it's parsed.
- *
- * @param request
- * @param response
- * @return
- * @throws IOException
- * @throws JDOMException
- */
- public static String downloadCommentedExcel(HttpServletRequest request, HttpServletResponse response) {
- String sequenceNum = request.getParameter("sequenceNum");
- GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");
- if (UtilValidate.isEmpty(sequenceNum) || UtilValidate.isEmpty(userLogin)) {
- Debug.logError("sequenceNum[" + sequenceNum + "] or userLogin is empty", module);
- return "error";
- }
- String userLoginId = userLogin.getString("userLoginId");
- Delegator delegator = (Delegator) request.getAttribute("delegator");
- GenericValue historyValue = null;
- try {
- historyValue = delegator.findOne("ExcelImportHistory", UtilMisc.toMap("userLoginId", userLoginId, "sequenceNum", Long.valueOf(sequenceNum)), false);
- } catch (NumberFormatException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- } catch (GenericEntityException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- }
- if (UtilValidate.isEmpty(historyValue)) {
- Debug.logError("No ExcelImportHistory value found by sequenceNum[" + sequenceNum + "] and userLoginId[" + userLoginId + "].", module);
- return "error";
- }
- String fileName = historyValue.getString("fileName");
- if (UtilValidate.isEmpty(fileName)) {
- fileName = sequenceNum + ".xlsx";
- }
- try {
- File file = FileUtil.getFile(InterfacePricatParser.tempFilesFolder + userLoginId + "/" + sequenceNum + ".xlsx");
- if (file.exists()) {
- Path path = Paths.get(file.getPath());
- byte[] bytes = Files.readAllBytes(path);
- UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8"));
- }
- } catch (MalformedURLException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- } catch (IOException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- }
- return "success";
- }
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.pricat;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.jdom.JDOMException;
+import org.apache.ofbiz.base.location.ComponentLocationResolver;
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.FileUtil;
+import org.apache.ofbiz.base.util.UtilHttp;
+import org.apache.ofbiz.base.util.UtilMisc;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.entity.Delegator;
+import org.apache.ofbiz.entity.GenericEntityException;
+import org.apache.ofbiz.entity.GenericValue;
+import org.apache.ofbiz.pricat.AbstractPricatParser;
+import org.apache.ofbiz.pricat.InterfacePricatParser;
+import org.apache.ofbiz.pricat.PricatParseExcelHtmlThread;
+
+public class PricatEvents {
+
+ public static final String module = PricatEvents.class.getName();
+
+ public static final String PricatLatestVersion = UtilProperties.getPropertyValue("pricat", "pricat.latest.version", "V1.1");
+
+ public static final String PricatFileName = "PricatTemplate_" + PricatLatestVersion + ".xlsx";
+
+ public static final String PricatPath = "component://pricat/webapp/pricat/downloads/";
+
+ /**
+ * Download excel template.
+ *
+ * @param request
+ * @param response
+ * @return
+ * @throws IOException
+ * @throws JDOMException
+ */
+ public static String downloadExcelTemplate(HttpServletRequest request, HttpServletResponse response) {
+ String templateType = request.getParameter("templateType");
+ if (UtilValidate.isEmpty(templateType)) {
+ return "error";
+ }
+ try {
+ String path = ComponentLocationResolver.getBaseLocation(PricatPath).toString();
+ String fileName = null;
+ if ("pricatExcelTemplate".equals(templateType)) {
+ fileName = PricatFileName;
+ }
+ if (UtilValidate.isEmpty(fileName)) {
+ return "error";
+ }
+ Path file = Paths.get(path + fileName);
+ byte[] bytes = Files.readAllBytes(file);
+ UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8"));
+ } catch (MalformedURLException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ } catch (IOException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ }
+ return "success";
+ }
+
+ /**
+ * Upload a pricat.
+ */
+ public static String pricatUpload(HttpServletRequest request, HttpServletResponse response) {
+ boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
+ if (isMultiPart) {
+ return "parse_pricat";
+ } else {
+ String action = request.getParameter("action");
+ if (UtilValidate.isNotEmpty(action) && "downloadPricat".equals(action)) {
+ String sequenceNumString = (String) request.getParameter("sequenceNum");
+ long sequenceNum = -1;
+ if (UtilValidate.isNotEmpty(sequenceNumString)) {
+ try {
+ sequenceNum = Long.valueOf(sequenceNumString);
+ } catch (NumberFormatException e) {
+ // do nothing
+ }
+ }
+ String originalPricatFileName = (String) request.getSession().getAttribute(PricatParseExcelHtmlThread.PRICAT_FILE);
+ String pricatFileName = originalPricatFileName;
+ if (sequenceNum > 0 && AbstractPricatParser.isCommentedExcelExists(request, sequenceNum)) {
+ GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");
+ String userLoginId = userLogin.getString("userLoginId");
+ pricatFileName = InterfacePricatParser.tempFilesFolder + userLoginId + "/" + sequenceNum + ".xlsx";
+ }
+ if (UtilValidate.isNotEmpty(pricatFileName) && UtilValidate.isNotEmpty(originalPricatFileName)) {
+ try {
+ Path path = Paths.get(pricatFileName);
+ byte[] bytes = Files.readAllBytes(path);
+ path = Paths.get(originalPricatFileName);
+ UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(path.getName(path.getNameCount() - 1).toString(), "UTF-8"));
+ } catch (MalformedURLException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ } catch (IOException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ }
+ request.getSession().removeAttribute(PricatParseExcelHtmlThread.PRICAT_FILE);
+ return "download";
+ }
+ }
+ }
+ return "success";
+ }
+
+ /**
+ * Download commented excel file after it's parsed.
+ *
+ * @param request
+ * @param response
+ * @return
+ * @throws IOException
+ * @throws JDOMException
+ */
+ public static String downloadCommentedExcel(HttpServletRequest request, HttpServletResponse response) {
+ String sequenceNum = request.getParameter("sequenceNum");
+ GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");
+ if (UtilValidate.isEmpty(sequenceNum) || UtilValidate.isEmpty(userLogin)) {
+ Debug.logError("sequenceNum[" + sequenceNum + "] or userLogin is empty", module);
+ return "error";
+ }
+ String userLoginId = userLogin.getString("userLoginId");
+ Delegator delegator = (Delegator) request.getAttribute("delegator");
+ GenericValue historyValue = null;
+ try {
+ historyValue = delegator.findOne("ExcelImportHistory", UtilMisc.toMap("userLoginId", userLoginId, "sequenceNum", Long.valueOf(sequenceNum)), false);
+ } catch (NumberFormatException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ } catch (GenericEntityException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ }
+ if (UtilValidate.isEmpty(historyValue)) {
+ Debug.logError("No ExcelImportHistory value found by sequenceNum[" + sequenceNum + "] and userLoginId[" + userLoginId + "].", module);
+ return "error";
+ }
+ String fileName = historyValue.getString("fileName");
+ if (UtilValidate.isEmpty(fileName)) {
+ fileName = sequenceNum + ".xlsx";
+ }
+ try {
+ File file = FileUtil.getFile(InterfacePricatParser.tempFilesFolder + userLoginId + "/" + sequenceNum + ".xlsx");
+ if (file.exists()) {
+ Path path = Paths.get(file.getPath());
+ byte[] bytes = Files.readAllBytes(path);
+ UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8"));
+ }
+ } catch (MalformedURLException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ } catch (IOException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ }
+ return "success";
+ }
+}
diff --git a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java
index fc7b43c..721ec50 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/ofbiz/pricat/sample/SamplePricatEvents.java
@@ -1,84 +1,84 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.ofbiz.pricat.sample;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URLEncoder;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.jdom.JDOMException;
-import org.apache.ofbiz.base.location.ComponentLocationResolver;
-import org.apache.ofbiz.base.util.Debug;
-import org.apache.ofbiz.base.util.UtilHttp;
-import org.apache.ofbiz.base.util.UtilProperties;
-import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.pricat.PricatEvents;
-
-public class SamplePricatEvents extends PricatEvents {
-
- public static final String module = SamplePricatEvents.class.getName();
-
- public static final String PricatLatestVersion = UtilProperties.getPropertyValue("pricat", "pricat.latest.version", "V1.1");
-
- public static final String DemoPricatFileName = "SamplePricatTemplate_" + PricatLatestVersion + ".xlsx";
-
- public static final String DemoPricatPath = "component://pricat/webapp/pricatdemo/downloads/";
-
- /**
- * Download excel template.
- *
- * @param request
- * @param response
- * @return
- * @throws IOException
- * @throws JDOMException
- */
- public static String downloadExcelTemplate(HttpServletRequest request, HttpServletResponse response) {
- String templateType = request.getParameter("templateType");
- if (UtilValidate.isEmpty(templateType)) {
- return "error";
- }
- try {
- String path = ComponentLocationResolver.getBaseLocation(DemoPricatPath).toString();
- String fileName = null;
- if ("pricatExcelTemplate".equals(templateType)) {
- fileName = DemoPricatFileName;
- }
- if (UtilValidate.isEmpty(fileName)) {
- return "error";
- }
- Path file = Paths.get(path + fileName);
- byte[] bytes = Files.readAllBytes(file);
- UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8"));
- } catch (MalformedURLException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- } catch (IOException e) {
- Debug.logError(e.getMessage(), module);
- return "error";
- }
- return "success";
- }
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.ofbiz.pricat.sample;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jdom.JDOMException;
+import org.apache.ofbiz.base.location.ComponentLocationResolver;
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.UtilHttp;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.pricat.PricatEvents;
+
+public class SamplePricatEvents extends PricatEvents {
+
+ public static final String module = SamplePricatEvents.class.getName();
+
+ public static final String PricatLatestVersion = UtilProperties.getPropertyValue("pricat", "pricat.latest.version", "V1.1");
+
+ public static final String DemoPricatFileName = "SamplePricatTemplate_" + PricatLatestVersion + ".xlsx";
+
+ public static final String DemoPricatPath = "component://pricat/webapp/pricatdemo/downloads/";
+
+ /**
+ * Download excel template.
+ *
+ * @param request
+ * @param response
+ * @return
+ * @throws IOException
+ * @throws JDOMException
+ */
+ public static String downloadExcelTemplate(HttpServletRequest request, HttpServletResponse response) {
+ String templateType = request.getParameter("templateType");
+ if (UtilValidate.isEmpty(templateType)) {
+ return "error";
+ }
+ try {
+ String path = ComponentLocationResolver.getBaseLocation(DemoPricatPath).toString();
+ String fileName = null;
+ if ("pricatExcelTemplate".equals(templateType)) {
+ fileName = DemoPricatFileName;
+ }
+ if (UtilValidate.isEmpty(fileName)) {
+ return "error";
+ }
+ Path file = Paths.get(path + fileName);
+ byte[] bytes = Files.readAllBytes(file);
+ UtilHttp.streamContentToBrowser(response, bytes, "application/octet-stream", URLEncoder.encode(fileName, "UTF-8"));
+ } catch (MalformedURLException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ } catch (IOException e) {
+ Debug.logError(e.getMessage(), module);
+ return "error";
+ }
+ return "success";
+ }
+}
diff --git a/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java b/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java
index 3d18c6c..2a10354 100644
--- a/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java
+++ b/specialpurpose/pricat/src/main/java/org/apache/poi/xssf/usermodel/OFBizPricatUtil.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.poi.xssf.usermodel;
-
-import org.apache.poi.ss.util.CellReference;
-import com.microsoft.schemas.vml.CTShape;
-
-public final class OFBizPricatUtil {
- public static void formatCommentShape(XSSFSheet sheet, CellReference cell) {
- XSSFVMLDrawing vml = sheet.getVMLDrawing(true);
- CTShape ctshape = vml.findCommentShape(cell.getRow(), cell.getCol());
- ctshape.setType("#_x0000_t202");
- }
-
- public static void formatCommentShape(XSSFSheet sheet, int rowNum, short colNum) {
- XSSFVMLDrawing vml = sheet.getVMLDrawing(true);
- CTShape ctshape = vml.findCommentShape(rowNum, colNum);
- ctshape.setType("#_x0000_t202");
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.poi.xssf.usermodel;
+
+import org.apache.poi.ss.util.CellReference;
+import com.microsoft.schemas.vml.CTShape;
+
+public final class OFBizPricatUtil {
+ public static void formatCommentShape(XSSFSheet sheet, CellReference cell) {
+ XSSFVMLDrawing vml = sheet.getVMLDrawing(true);
+ CTShape ctshape = vml.findCommentShape(cell.getRow(), cell.getCol());
+ ctshape.setType("#_x0000_t202");
+ }
+
+ public static void formatCommentShape(XSSFSheet sheet, int rowNum, short colNum) {
+ XSSFVMLDrawing vml = sheet.getVMLDrawing(true);
+ CTShape ctshape = vml.findCommentShape(rowNum, colNum);
+ ctshape.setType("#_x0000_t202");
+ }
+}