blob: 5460a34cd404e9ca78696088726975435ede4cf1 [file] [log] [blame]
/*
* 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.taglibs.rdc.core;
import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.taglibs.rdc.RDCUtils;
/**
* <p>This is the implementation of the RDC helper tag group.
* Group is a container with pluggable DM strategies.</p>
*
* @author Rahul Akolkar
*/
public class GroupTag extends SimpleTagSupport {
// Error messages (to be i18n'zed)
private static final String ERR_NO_STRATEGY = "<!-- GroupTag: " +
"strategy attribute value - \"{0}\" contains whitespace only -->\n";
private static final String ERR_NO_SUCH_STRATEGY = "<!-- GroupTag: No " +
"strategy class found - \"{0}\" -->\n";
private static final String ERR_NOT_A_DM_STRATEGY = "<!-- GroupTag: " +
"Class - \"{0}\" does not implement the DialogManager interface -->\n";
private static final String ERR_INSTANTIATING_STRATEGY = "<!-- GroupTag:" +
" Error instantiating the specified strategy class - \"{0}\" -->\n";
// Logging
private static Log log = LogFactory.getLog(GroupTag.class);
// CLASS PROPERTIES
// The unique identifier associated with the group
private String id;
// Holds the submit url
private String submit;
// Holds the configuration details for the dialog management strategy
// The interpretation of this attribute is upto the DM strategy plugged in
private String config;
// Indicates whether group level confirmation is requested
// Overrides atom level confirmation, if specified
private Boolean confirm;
// The class name that implements the dialog management strategy
private String strategy;
// The DialogManager overseeing this group instance
private DialogManager dm = null;
/* Constructor */
public GroupTag() {
super();
id = null;
submit = null;
config = null;
strategy = null;
confirm = Boolean.FALSE;
dm = null;
}
/**
* Gets the ID of the group
*
* @return ID The group's strategy
*/
public String getId() {
return id;
}
/**
* Sets the id of the group
*
* @param id The group's id
*/
public void setId(String id) {
this.id = id;
}
/**
* Gets the submit URL where group should submit
*
* @return submit The group's submit URL
*/
public String getSubmit() {
return submit;
}
/**
* Sets the submit URL for the group
*
* @param submit The group's submit URL
*/
public void setSubmit(String submit) {
this.submit = submit;
}
/**
* Gets the configuration URI of the group
*
* @return config The group's configuration URI
*/
public String getConfig() {
return config;
}
/**
* Sets the configuration URI of the group
*
* @param config The group's configuration URI
*/
public void setConfig(String config) {
this.config = config;
}
/**
* Get the group level confirmation
*
* @return confirm
*/
public Boolean getConfirm() {
return confirm;
}
/**
* Set the group level confirmation
*
* @param confirm The group confirmation
*/
public void setConfirm(Boolean confirm) {
this.confirm = confirm;
}
/**
* Get the class name that implements the DM strategy
*
* @return strategy the class name
*/
public String getStrategy() {
return strategy;
}
/**
* Set the class name that implements the DM strategy
*
* @param strategy the class name
*/
public void setStrategy(String strategy) {
this.strategy = strategy;
}
/**
* Make JspContext visible to the DM strategy
*
* @return JspContext
*/
public JspContext getJspContext() {
return super.getJspContext();
}
/**
* Has the state machine for the group
*
* Uses a pluggable dialog management strategy
*/
public void doTag() throws JspException, IOException {
if (dm == null) {
PageContext ctx = (PageContext) getJspContext();
try {
dm = getStrategyInstance(ctx);
} catch (ClassNotFoundException cnfe) {
write(ctx, ERR_NO_SUCH_STRATEGY,
new Object[] {strategy}, cnfe);
}
}
if (submit == null || submit.length() == 0) {
submit = ((HttpServletRequest) ((PageContext) getJspContext()).
getRequest()).getRequestURI();
}
dm.setGroupTag(this);
if (!dm.initialize(getJspContext(), getJspBody())) {
return;
}
dm.collect(getJspContext(), getJspBody());
// Deprecated (since RDC 1.1)
dm.confirm();
dm.finish(getJspContext());
}
/**
* Instantiate the strategy for this group instance.
*
* @param ctx The host JSP PageContext
* @return DialogManager The DM strategy instance
*/
private DialogManager getStrategyInstance(PageContext ctx)
throws ClassNotFoundException {
final Object[] errMsgArgs = new Object[] {strategy};
if (RDCUtils.isStringEmpty(strategy)) {
write(ctx, ERR_NO_STRATEGY, errMsgArgs, null);
return null;
}
Class dmClass = null;
DialogManager dialogManager = null;
try {
dmClass = Class.forName(strategy);
} catch (ClassNotFoundException cnfe) {
// Try the classloader for this thread
dmClass = Class.forName(strategy, true, Thread.currentThread().
getContextClassLoader());
} catch (Exception e) {
// Log error
log.error(e.getMessage(), e);
write(ctx, ERR_INSTANTIATING_STRATEGY, errMsgArgs, null);
}
if (dmClass != null) {
try {
dialogManager = (DialogManager) dmClass.newInstance();
} catch (ClassCastException cce) {
write(ctx, ERR_NOT_A_DM_STRATEGY, errMsgArgs, cce);
} catch (Exception e) {
// Log error
log.error(e.getMessage(), e);
write(ctx, ERR_INSTANTIATING_STRATEGY, errMsgArgs, e);
}
}
return dialogManager;
}
/**
* Attempt to write given message to JSP writer.
*
* @param ctx The host JSP PageContext
* @param msg The message to be sent to the JSP writer
* @return boolean Outcome of write attempt
*/
private void write(final PageContext ctx, final String errMsgName,
final Object[] msgArgs, final Exception e) {
MessageFormat msgFormat = new MessageFormat(errMsgName);
String errMsg = msgFormat.format(msgArgs);
// Log error
if (e == null) {
log.error(errMsg);
} else {
log.error(errMsg, e);
}
// Attempt to send message to client
try {
ctx.getOut().write(errMsg);
} catch (IOException ioe) {
log.error(ioe.getMessage(),ioe);
}
}
}