Admin.java
/*
* $Source$
* $Revision$
*
* Copyright (C) 2000 William Chesters
*
* Part of Melati (http://melati.org), a framework for the rapid
* development of clean, maintainable web applications.
*
* Melati is free software; Permission is granted to copy, distribute
* and/or modify this software under the terms either:
*
* a) the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version,
*
* or
*
* b) any version of the Melati Software License, as published
* at http://melati.org
*
* You should have received a copy of the GNU General Public License and
* the Melati Software License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
* GNU General Public License and visit http://melati.org to obtain the
* Melati Software License.
*
* Feel free to contact the Developers of Melati (http://melati.org),
* if you would like to work out a different arrangement than the options
* outlined here. It is our intention to allow Melati to be used by as
* wide an audience as possible.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Contact details for copyright holder:
*
* William Chesters <williamc At paneris.org>
* http://paneris.org/~williamc
* Obrechtstraat 114, 2517VX Den Haag, The Netherlands
*/
package org.melati.admin;
import java.util.Vector;
import java.util.Enumeration;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.melati.Melati;
import org.melati.PoemContext;
import org.melati.servlet.FormDataAdaptor;
import org.melati.servlet.InvalidUsageException;
import org.melati.servlet.Form;
import org.melati.servlet.TemplateServlet;
import org.melati.template.ClassNameTempletLoader;
import org.melati.template.JSONMarkupLanguage;
import org.melati.template.MarkupLanguage;
import org.melati.template.ServletTemplateContext;
import org.melati.template.FormParameterException;
import org.melati.poem.AccessToken;
import org.melati.poem.AccessPoemException;
import org.melati.poem.BaseFieldAttributes;
import org.melati.poem.Capability;
import org.melati.poem.Column;
import org.melati.poem.ColumnInfo;
import org.melati.poem.ColumnInfoTable;
import org.melati.poem.ColumnTypePoemType;
import org.melati.poem.Database;
import org.melati.poem.DeletionIntegrityPoemException;
import org.melati.poem.DisplayLevel;
import org.melati.poem.ExecutingSQLPoemException;
import org.melati.poem.Field;
import org.melati.poem.FieldAttributes;
import org.melati.poem.Initialiser;
import org.melati.poem.NoSuchColumnPoemException;
import org.melati.poem.Persistent;
import org.melati.poem.PoemException;
import org.melati.poem.PoemLocale;
import org.melati.poem.PoemThread;
import org.melati.poem.PoemTypeFactory;
import org.melati.poem.ReferencePoemType;
import org.melati.poem.Setting;
import org.melati.poem.Table;
import org.melati.poem.TableInfo;
import org.melati.poem.TableInfoTable;
import org.melati.poem.ValidationPoemException;
import org.melati.util.CountedDumbPagedEnumeration;
import org.melati.poem.util.EnumUtils;
import org.melati.poem.util.MappedEnumeration;
import org.melati.util.MelatiBugMelatiException;
import org.melati.util.MelatiIOException;
import org.melati.util.MelatiRuntimeException;
/**
* Melati template servlet for database administration.
* <p>
* This class defines {@link #doTemplateRequest(Melati, ServletTemplateContext)}
* and methods it calls to interpret requests, depending on the current table
* and object, if any.
* <p>
* Java methods with names ending "<code>Template</code>" and taking a
* {@link ServletTemplateContext} and {@link Melati} as arguments are generally
* called by {@link #doTemplateRequest(Melati, ServletTemplateContext)}) to
* implement corresponding request methods.
* {@link #modifyTemplate(ServletTemplateContext, Melati)} and associated
* methods are slight variations.
* <p>
* {@link #adminTemplate(String)} is called in all cases
* to return the template path. The name of the template is usually the same as
* the request method but not if the same template is used for more than one
* method or the template served depends on how request processing proceeds.
* <p>
* These methods are called to modify the context:
* <ul>
* <li>{@link #popupSelect(ServletTemplateContext, Melati)}</li>
* </ul>
*
* TODO Review working of where clause for dates
* TODO Move Nav icons into PrimarySelect
* TODO Make Chooser JS agnostic
* TODO Make Navigation JS agnostic
* TODO Logout fails to work if remember me is ticked
* TODO Order by field f orders on fields troid, not field ordering
* TODO Enable non-paged output of selection by adding paged parameter to selectionTemplate
* FIXME primaryDisplayTable should not be static as this messes with DB switching
*/
public class Admin extends TemplateServlet {
private static final long serialVersionUID = 8451412887121581757L;
private static String screenStylesheetURL = null;
private static String primaryDisplayTable = null;
private static String homepageURL = null;
/**
* Creates a row for a table using field data in a template context.
*/
protected static Persistent create(Table<?> table,
final ServletTemplateContext context) {
Persistent result = table.create(new Initialiser() {
public void init(Persistent object) throws AccessPoemException,
ValidationPoemException {
Form.extractFields(context, object);
}
});
result.postEdit(true);
return result;
}
/**
* Return the resource path for an admin template.
*/
protected static String adminTemplate(String name) {
return "org/melati/admin/" + name;
}
/**
* @return a DSD for the database
*/
protected static String dsdTemplate(ServletTemplateContext context) {
// Webmacro security prevents access from within template
// Note: getPackage() can return null dependant upon
// the classloader so we have to chomp the class name
String c = PoemThread.database().getClass().getName();
int dot = c.lastIndexOf('.');
String p = c.substring(0, dot);
context.put("package", p);
return adminTemplate("DSD");
}
/**
* @return primary select template
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected static String primarySelectTemplate(ServletTemplateContext context,
Melati melati) throws PoemException {
final Table table = melati.getTable();
Field<Object> primaryCriterion;
Column<?> column = table.primaryCriterionColumn();
if (column != null) {
String sea = context.getFormField("field_" + column.getName());
primaryCriterion = new Field<Object>(
sea == null ?
(
melati.getObject() == null ?
null : column.getRaw(melati.getObject()))
: column.getType().rawOfString(sea),
new BaseFieldAttributes(column,column.getType().withNullable(true)));
} else
primaryCriterion = null;
context.put("primaryCriterion", primaryCriterion);
return adminTemplate("PrimarySelect");
}
/**
* Return template for a selection of records from a table.
*/
protected static String selectionTemplate(ServletTemplateContext context,
Melati melati) {
String templateName = context.getFormField("template");
if (templateName == null) {
selection(context, melati, true);
return adminTemplate("Selection");
} else {
selection(context, melati, false);
return adminTemplate(templateName);
}
}
/**
* Select records based upon query parameters and return JSON template.
*/
protected static String selectionJsonTemplate(ServletTemplateContext context,
Melati melati) {
MarkupLanguage ml = new JSONMarkupLanguage(
melati,
ClassNameTempletLoader.getInstance(),
PoemLocale.HERE);
melati.setMarkupLanguage(ml);
context.put("ml", ml); // an HTML ml has already been put into context
melati.setResponseContentType("application/json");
context.put("typeConverter", new PoemGvisTypeConverter());
selection(context, melati, false);
return adminTemplate("SelectionJSON");
}
/**
* Implements request to display a selection of records from a table in the
* right hand pane.
*
* @return SelectionRight template.
*/
protected static String selectionRightTemplate(
ServletTemplateContext context, Melati melati) {
selection(context, melati, true);
context.put("inRight", Boolean.TRUE);
return adminTemplate("Selection");
}
/**
* Prepares the context in preparation for serving a template to view a
* selection of rows.
* <p>
* Any form fields in the context with names starting "field_" are assumed to
* hold values that must be matched in selected rows (if not null).
* <p>
* An encoding of the resulting whereClause is added to the context. "AND" is
* replaced by an & separator.
* <p>
* A form field with name "start" is assumed to hold the number of the start
* row in the result set. The default is zero. The next 20 rows are selected
* and added as to the context as "results".
*
* @return The prepared context.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected static ServletTemplateContext selection(
ServletTemplateContext context, Melati melati, boolean paged) {
final Table<?> table = melati.getTable();
final Database database = table.getDatabase();
// sort out search criteria
final Persistent criteria = table.newPersistent();
Vector<Object> whereClause = new Vector<Object>();
for (Enumeration<Column<?>> c = table.columns(); c.hasMoreElements();) {
Column<?> column = c.nextElement();
String name = "field_" + column.getName();
String fieldValue = Form.getFieldNulled(context, name);
if (fieldValue != null) {
column
.setRaw_unsafe(criteria, column.getType().rawOfString(fieldValue));
// FIXME Needs to work for dates
whereClause.addElement(name + "=" + melati.urlEncode(fieldValue));
}
}
context.put("whereClause", EnumUtils.concatenated("&", whereClause
.elements()));
// sort out ordering
ReferencePoemType searchColumnsType = getSearchColumnsType(database, table);
Vector<Object> orderings = new Vector<Object>();
Vector<Object> orderQuery = new Vector<Object>();
for (int o = 0; o <= table.displayColumnsCount(DisplayLevel.summary); ++o) {
String name = "field_order-" + o;
String orderColumnIDString = Form.getFieldNulled(context, name);
Integer orderColumnID;
if (orderColumnIDString != null) {
String toggleName = "field_order-" + o + "-toggle";
String orderColumnSortOrderToggle = Form.getFieldNulled(context,
toggleName);
Boolean toggle = new Boolean(orderColumnSortOrderToggle);
orderColumnID = (Integer) searchColumnsType
.rawOfString(orderColumnIDString);
ColumnInfo info = (ColumnInfo) searchColumnsType
.cookedOfRaw(orderColumnID);
String desc = Boolean.TRUE.equals(info.getSortdescending()) ? (Boolean.TRUE
.equals(toggle) ? "" : " DESC")
: (Boolean.TRUE.equals(toggle) ? " DESC" : "");
orderings.addElement(database.quotedName(info.getName()) + desc);
orderQuery.addElement(name + "=" + orderColumnIDString);
}
}
String orderBySQL = null;
if (orderings.elements().hasMoreElements())
orderBySQL = EnumUtils.concatenated(", ", orderings.elements());
context.put("orderClause", EnumUtils.concatenated("&", orderQuery
.elements()));
context.put("inclusionColumns", inclusionColumns(context, table));
int start = 0;
String startString = Form.getFieldNulled(context, "start");
if (startString != null) {
try {
start = Math.max(0, Integer.parseInt(startString));
} catch (NumberFormatException e) {
throw new MelatiBugMelatiException("How did you get that in there?",
new FormParameterException("start", "Param must be an Integer"));
}
}
if (paged) {
final int resultsPerPage = 20;
context.put("results",
new CountedDumbPagedEnumeration(
table.selection(criteria, orderBySQL, false, false),
start, resultsPerPage,
table.cachedCount(criteria, false, false).count())
);
} else {
context.put("results", table.selection(criteria, orderBySQL, false, false));
}
return context;
}
static Vector<Column<?>> inclusionColumns(
ServletTemplateContext context, final Table<?> table) {
// find out which columns to return, default to summary columns
Vector<Column<?>> inclusionColumns = new Vector<Column<?>>();
for (int inc = 0; inc <= table.displayColumnsCount(DisplayLevel.record); ++inc) {
String formFieldName = "field_include-" + inc;
String includeColumnName = Form.getFieldNulled(context, formFieldName);
if (includeColumnName != null) {
Column<?> c;
try {
c = table.getColumn(includeColumnName);
inclusionColumns.add(c);
} catch (NoSuchColumnPoemException e) {
throw new IllegalArgumentException(
"Field named '" + includeColumnName + "' not found in table " + table.getName(),e);
}
}
}
if (inclusionColumns.size() == 0){
inclusionColumns = EnumUtils.vectorOf(table.getSummaryDisplayColumns());
}
return inclusionColumns;
}
/**
* Implements the field search/selection request method.
*/
protected static String popupSelectTemplate(ServletTemplateContext context,
Melati melati) throws PoemException {
popupSelect(context, melati);
return adminTemplate("PopupSelect");
}
@SuppressWarnings({ "rawtypes", "unchecked"})
protected static ServletTemplateContext popupSelect(ServletTemplateContext context,
Melati melati) throws PoemException {
final Table table = melati.getTable();
final Database database = table.getDatabase();
// sort out search criteria
final Persistent criteria = table.newPersistent();
MappedEnumeration<Field<?>, Column<?>> criterias = new MappedEnumeration<Field<?>, Column<?>>(table
.getSearchCriterionColumns()) {
public Field<?> mapped(Column<?> c) {
return c.asField(criteria).withNullable(true);
}
};
context.put("criteria", EnumUtils.vectorOf(criterias));
ReferencePoemType searchColumnsType = getSearchColumnsType(database, table);
Vector<Field<?>> orderings = new Vector<Field<?>>();
// NOTE Order by searchable columns, this could be summary columns
Enumeration<Integer> searchColumns = searchColumnsType.possibleRaws();
int o = 0;
while (searchColumns.hasMoreElements()) {
String name = "order-" + o++;
orderings.addElement(new Field(searchColumns.nextElement(),
new BaseFieldAttributes(name, searchColumnsType)));
}
context.put("orderings", orderings);
return context;
}
/**
* @return a type whose whose possible members are the search columns of the table
*/
private static ReferencePoemType getSearchColumnsType(final Database database, final Table<?> table) {
return new ReferencePoemType(database
.getColumnInfoTable(), false) {
protected Enumeration<Integer> _possibleRaws() {
return new MappedEnumeration<Integer, Column<?>>(table.getSearchCriterionColumns()) {
public Integer mapped(Column<?> column) {
return column.getColumnInfo().getTroid();
}
};
}
};
}
/**
* @return primary select template
*/
protected static String selectionWindowPrimarySelectTemplate(
ServletTemplateContext context, Melati melati) throws PoemException {
context.put("inPopup", Boolean.TRUE);
return primarySelectTemplate(context, melati);
}
/**
* @return select template (a selection of records from a table)
*/
protected static String selectionWindowSelectionTemplate(
ServletTemplateContext context, Melati melati) {
selection(context, melati, true);
context.put("inPopup", Boolean.TRUE);
return adminTemplate("Selection");
}
/**
* Returns the Add template after placing the table and fields for the new row
* in the context using any field values already in the context.
*
* If the table is a table meta data table, or a column meta data table then
* the appropriate extras are added to the co0ntext.
*
* The Form does not normally contain values, but this could be used as a
* mechanism for providing defaults.
*/
@SuppressWarnings("unchecked")
protected static String addTemplate(final ServletTemplateContext context,
Melati melati) throws PoemException {
/*
* Enumeration fields = new MappedEnumeration(melati.getTable().columns()) {
* public Object mapped(Object column) { String stringValue =
* context.getForm("field_" + ((Column)column).getName()); Object value =
* null; if (stringValue != null) value =
* ((Column)column).getType().rawOfString(stringValue); return new
* Field(value, (Column)column); } }; context.put("fields", fields);
*/
// getDetailDisplayColumns() == columns() but could exclude some in theory
Enumeration<Column<?>> columns = melati.getTable().getDetailDisplayColumns();
Vector<Field<?>> fields = new Vector<Field<?>>();
while (columns.hasMoreElements()) {
Column<?> column = columns.nextElement();
String stringValue = context.getFormField("field_" + column.getName());
Object value = null;
if (stringValue != null)
value = column.getType().rawOfString(stringValue);
else if (column.getType() instanceof ColumnTypePoemType)
value = PoemTypeFactory.STRING.getCode();
fields.add(new Field<Object>(value, (FieldAttributes<Object>) column));
}
if (melati.getTable() instanceof TableInfoTable) {
Database database = melati.getDatabase();
// Compose field for naming the TROID column: the display name and
// description are redundant, since they not used in the template
final int troidHeight = 1;
final int troidWidth = 20;
Field<String> troidNameField = new Field<String>("id", new BaseFieldAttributes<String>(
"troidName", "Troid column", "Name of TROID column", database
.getColumnInfoTable().getNameColumn().getType(), troidWidth,
troidHeight, null, false, true, true));
fields.add(troidNameField);
}
context.put("fields", fields.elements());
return adminTemplate("Add");
}
/**
* Returns the Updated template after creating a new row using field data in
* the context.
* <p>
* If successful the template will say so while reloading according to the
* returnTarget and returnURL values from the Form in context.
*/
protected static String addUpdateTemplate(ServletTemplateContext context,
Melati melati) throws PoemException {
Persistent newPersistent = create(melati.getTable(), context);
if (melati.getTable() instanceof TableInfoTable)
melati.getDatabase().addTableAndCommit((TableInfo) newPersistent,
context.getFormField("field_troidName"));
if (melati.getTable() instanceof ColumnInfoTable)
((ColumnInfo) newPersistent).getTableinfo().actualTable()
.addColumnAndCommit((ColumnInfo) newPersistent);
melati.setPoemContext(new PoemContext(newPersistent));
melati.loadTableAndObject();
//context.put("object", newPersistent);
melati.getResponse().setStatus(201);
return adminTemplate("Updated");
}
/**
* Returns the Updated template after modifying the current row according to
* field values in the context.
* <p>
* If successful the template will say so while reloading according to the
* returnTarget and returnURL values from the Form in context.
*/
protected static String updateTemplate(ServletTemplateContext context,
Melati melati) throws PoemException {
Persistent object = melati.getObject();
object.preEdit();
Form.extractFields(context, object);
object.postEdit(false);
return adminTemplate("Updated");
}
protected static String deleteTemplate(ServletTemplateContext context,
Melati melati) throws PoemException {
try {
if (melati.getTable().getName().equalsIgnoreCase("tableinfo")) {
TableInfo tableInfo = (TableInfo) melati.getObject();
melati.getDatabase().deleteTableAndCommit(tableInfo);
} else if (melati.getTable().getName().equalsIgnoreCase("columninfo")) {
ColumnInfo columnInfo = (ColumnInfo) melati.getObject();
columnInfo.getTableinfo().actualTable().deleteColumnAndCommit(
columnInfo);
} else
melati.getObject().delete();
melati.getPoemContext().setTroid(null);
melati.loadTableAndObject();
return adminTemplate("Updated");
} catch (DeletionIntegrityPoemException e) {
context.put("references", e.references);
context.put("returnURL", melati.getSameURL() + "?action=Delete");
return adminTemplate("DeleteFailure");
}
}
protected static String duplicateTemplate(ServletTemplateContext context,
Melati melati) throws PoemException {
Persistent dup = melati.getObject().duplicated();
Form.extractFields(context, dup);
try {
dup.getTable().create(dup);
} catch (ExecutingSQLPoemException e) {
throw new NonUniqueKeyValueAnticipatedException(e);
}
melati.setPoemContext(new PoemContext(dup));
melati.loadTableAndObject();
//context.put("object", dup);
return adminTemplate("Updated");
}
/**
* Implements request method "Update".
* <p>
* Calls another method depending on the requested action.
*
* @see #updateTemplate(ServletTemplateContext, Melati)
* @see #deleteTemplate(ServletTemplateContext, Melati)
* @see #duplicateTemplate(ServletTemplateContext, Melati)
*/
protected static String modifyTemplate(ServletTemplateContext context,
Melati melati) throws FormParameterException {
String action = melati.getRequest().getParameter("action");
if ("Update".equals(action))
return updateTemplate(context, melati);
if ("Delete".equals(action))
return deleteTemplate(context, melati);
if ("Duplicate".equals(action))
return duplicateTemplate(context, melati);
else
throw new MelatiBugMelatiException("How did you get that in there?",
new FormParameterException(
"action", "Bad action from Edit: " + action));
}
protected static String uploadTemplate(ServletTemplateContext context)
throws PoemException {
context.put("field", context.getFormField("field"));
return adminTemplate("Upload");
}
/**
* Finished uploading.
*
* If you want the system to display the file you need to set your melati-wide
* FormDataAdaptorFactory, in org.melati.MelatiConfig.properties, to something
* that returns a valid URL, for instance, PoemFileDataAdaptorFactory;
* (remember to set your UploadDir and UploadURL in the Setting table).
*
* @param context
* the {@link ServletTemplateContext} in use
* @return a template name
*/
protected static String uploadDoneTemplate(ServletTemplateContext context)
throws PoemException {
String field = context.getFormField("field");
context.put("field", field);
String url = context.getMultipartFormField("file").getDataURL();
if (url == null)
throw new NullUrlDataAdaptorException(context.getMultipartFormField("file").getFormDataAdaptor());
context.put("url", url);
return adminTemplate("UploadDone");
}
static class NullUrlDataAdaptorException extends MelatiRuntimeException {
private static final long serialVersionUID = 1L;
private FormDataAdaptor fda;
NullUrlDataAdaptorException(FormDataAdaptor fda) {
this.fda = fda;
}
/** @return the message */
public String getMessage() {
return "The configured FormDataAdaptor (" + fda.getClass().getName() + ") returns a null URL.";
}
}
protected static String setupTemplate(ServletTemplateContext context,
Melati melati) {
screenStylesheetURL = melati.getDatabase().getSettingTable().ensure(
Admin.class.getName() + ".ScreenStylesheetURL", "/blue.css",
"ScreenStylesheetURL",
"path to stylesheet, relative to melati-static, starting with a slash")
.getValue();
primaryDisplayTable = melati.getDatabase().getSettingTable().ensure(
Admin.class.getName() + ".PrimaryDisplayTable", "setting",
"PrimaryDisplayTable", "The default table to display").getValue();
Setting homepageURLSetting = melati.getDatabase().getSettingTable().ensure(
Admin.class.getName() + ".HomepageURL", "http://www.melati.org/",
"HomepageURL", "The home page for this database");
homepageURL = homepageURLSetting.getValue();
// HACK Not very satisfactory, but only to enable testing
//context.put("object", homepageURLSetting);
// If we wanted to get RESTful at this point, but it is a bit nasty as a UI
// melati.getResponse().setHeader("Location",melati.sameURLWith("action", ""));
return adminTemplate("Updated");
}
protected String doTemplateRequest(Melati melati,
ServletTemplateContext context) throws Exception {
if (melati.getMethod().equals("Proxy"))
return proxy(melati, context);
melati.getSession().setAttribute("generatedByMelatiClass",this.getClass().getName());
context.put("admin", new AdminUtils(melati));
String table = Form.getFieldNulled(context, "table");
if (table != null) {
if (!table.equals(melati.getTable().getName())) {
melati.getPoemContext().setTable(table);
melati.getPoemContext().setTroid(null);
melati.loadTableAndObject();
}
}
if (Form.getFieldNulled(context, "goto") != null)
melati.getResponse().sendRedirect(Form.getField(context, "goto", null));
melati.setPassbackExceptionHandling();
melati.setResponseContentType("text/html");
Capability admin = PoemThread.database().getCanAdminister();
AccessToken token = PoemThread.accessToken();
if (!token.givesCapability(admin))
throw new AccessPoemException(token, admin);
if (melati.getMethod() == null)
return adminTemplate("Main");
if (melati.getMethod().equals("blank"))
return adminTemplate("blank");
if (melati.getMethod().equals("setup"))
return setupTemplate(context, melati);
if (melati.getMethod().equals("Main"))
return adminTemplate("Main");
if (melati.getMethod().equals("Top"))
return adminTemplate("Top");
if (melati.getMethod().equals("Summary"))
return adminTemplate("Summary");
if (melati.getMethod().equals("UploadDone"))
return uploadDoneTemplate(context);
if (melati.getMethod().equals("Record"))
return adminTemplate("Record");
if (melati.getMethod().equals("Selection"))
return selectionTemplate(context, melati);
if (melati.getMethod().equals("SelectionJSON"))
return selectionJsonTemplate(context, melati);
if (melati.getObject() != null) {
if (melati.getMethod().equals("Update"))
return modifyTemplate(context, melati);
if (melati.getObject() instanceof AdminSpecialised) {
String templateName = ((AdminSpecialised) melati.getObject())
.adminHandle(melati, melati.getMarkupLanguage());
if (templateName != null)
return templateName;
}
}
if (melati.getTable() != null) {
if (melati.getMethod().equals("Tree"))
return adminTemplate("Tree");
if (melati.getMethod().equals("Bottom"))
return adminTemplate("Bottom");
if (melati.getMethod().equals("Table"))
return adminTemplate("Table");
if (melati.getMethod().equals("PrimarySelect"))
return primarySelectTemplate(context, melati);
if (melati.getMethod().equals("EditHeader"))
return adminTemplate("EditHeader");
if (melati.getMethod().equals("Edit"))
return adminTemplate("Edit");
if (melati.getMethod().equals("Upload"))
return uploadTemplate(context);
if (melati.getMethod().equals("SelectionRight"))
return selectionRightTemplate(context, melati);
if (melati.getMethod().equals("Navigation"))
return adminTemplate("Navigation");
if (melati.getMethod().equals("PopUp"))
return popupSelectTemplate(context, melati);
if (melati.getMethod().equals("SelectionWindow"))
return adminTemplate("SelectionWindow");
if (melati.getMethod().equals("SelectionWindowPrimarySelect"))
return selectionWindowPrimarySelectTemplate(context, melati);
if (melati.getMethod().equals("SelectionWindowSelection"))
return selectionWindowSelectionTemplate(context, melati);
if (melati.getMethod().equals("Add"))
return addTemplate(context, melati);
if (melati.getMethod().equals("Created"))
return addUpdateTemplate(context, melati);
}
if (melati.getMethod().equals("DSD"))
return dsdTemplate(context);
throw new InvalidUsageException(this, melati.getPoemContext());
}
private String proxy(Melati melati, ServletTemplateContext context) {
if (melati.getSession().getAttribute("generatedByMelatiClass") == null)
throw new AnticipatedException("Only available from within an Admin generated page");
String method = melati.getRequest().getMethod();
String url = melati.getRequest().getQueryString();
HttpServletResponse response = melati.getResponse();
HttpMethod httpMethod = null;
try {
HttpClient client = new HttpClient();
if (method.equals("GET"))
httpMethod = new GetMethod(url);
else if (method.equals("POST"))
httpMethod = new PostMethod(url);
else if (method.equals("PUT"))
httpMethod = new PutMethod(url);
else if (method.equals("HEAD"))
httpMethod = new HeadMethod(url);
else
throw new RuntimeException("Unexpected method '" + method + "'");
try {
httpMethod.setFollowRedirects(true);
client.executeMethod(httpMethod);
for (Header h : httpMethod.getResponseHeaders()) {
response.setHeader(h.getName(), h.getValue());
}
response.setStatus(httpMethod.getStatusCode());
response.setHeader("Cache-Control", "no-cache");
byte[] outputBytes = httpMethod.getResponseBody();
if (outputBytes != null) {
response.setBufferSize(outputBytes.length);
response.getWriter().write(new String(outputBytes));
response.getWriter().flush();
}
} catch (Exception e) {
throw new MelatiIOException(e);
}
} finally {
if (httpMethod != null)
httpMethod.releaseConnection();
}
return null;
}
/**
* @return the screenStylesheetURL
*/
static String getScreenStylesheetURL() {
return screenStylesheetURL;
}
/**
* @param screenStylesheetURL the screenStylesheetURL to set
*/
static void setScreenStylesheetURL(String screenStylesheetURL) {
Admin.screenStylesheetURL = screenStylesheetURL;
}
/**
* @return the primaryDisplayTable
*/
static String getPrimaryDisplayTable() {
return primaryDisplayTable;
}
/**
* @param primaryDisplayTable the primaryDisplayTable to set
*/
static void setPrimaryDisplayTable(String primaryDisplayTable) {
Admin.primaryDisplayTable = primaryDisplayTable;
}
/**
* @return the homepageURL
*/
static String getHomepageURL() {
return homepageURL;
}
/**
* @param homepageURL the homepageURL to set
*/
static void setHomepageURL(String homepageURL) {
Admin.homepageURL = homepageURL;
}
}