use of org.apache.velocity.VelocityContext in project xwiki-platform by xwiki.
the class DefaultVelocityManager method getVelocityContext.
@Override
public VelocityContext getVelocityContext() {
ScriptVelocityContext velocityContext;
// Make sure the velocity context support ScriptContext synchronization
VelocityContext currentVelocityContext = getCurrentVelocityContext();
if (currentVelocityContext instanceof ScriptVelocityContext) {
velocityContext = (ScriptVelocityContext) currentVelocityContext;
} else {
velocityContext = new ScriptVelocityContext(currentVelocityContext, this.reservedBindings);
this.execution.getContext().setProperty(VelocityExecutionContextInitializer.VELOCITY_CONTEXT_ID, velocityContext);
}
// Synchronize with ScriptContext
ScriptContext scriptContext = this.scriptContextManager.getScriptContext();
velocityContext.setScriptContext(scriptContext);
// Velocity specific bindings
XWikiContext xcontext = this.xcontextProvider.get();
// Add the "context" binding which is deprecated since 1.9.1.
velocityContext.put("context", new DeprecatedContext(xcontext));
return velocityContext;
}
use of org.apache.velocity.VelocityContext in project xwiki-platform by xwiki.
the class DefaultVelocityManager method getVelocityEngine.
/**
* @return the Velocity Engine corresponding to the current execution context. More specifically returns the
* Velocity Engine for the current skin since each skin has its own Velocity Engine so that each skin can
* have global velocimacros defined
* @throws XWikiVelocityException in case of an error while creating a Velocity Engine
*/
@Override
public VelocityEngine getVelocityEngine() throws XWikiVelocityException {
// Note: For improved performance we cache the Velocity Engines in order not to
// recreate them all the time. The key we use is the location to the skin's macro.vm
// file since caching on the skin would create more Engines than needed (some skins
// don't have a macros.vm file and some skins inherit from others).
// Create a Velocity context using the Velocity Manager associated to the current skin's
// macros.vm
// Get the location of the skin's macros.vm file
XWikiContext xcontext = this.xcontextProvider.get();
final Template template;
if (xcontext != null && xcontext.getWiki() != null) {
template = getVelocityEngineMacrosTemplate();
} else {
template = null;
}
String cacheKey = template != null ? template.getId() : "default";
// Get the Velocity Engine to use
VelocityEngine velocityEngine = this.velocityFactory.getVelocityEngine(cacheKey);
if (velocityEngine == null) {
// created only when a new skin is created and not be on the main execution path.
synchronized (this) {
velocityEngine = this.velocityFactory.getVelocityEngine(cacheKey);
if (velocityEngine == null) {
// Gather the global Velocity macros that we want to have. These are skin dependent.
Properties properties = new Properties();
// Loader
if (!this.velocityConfiguration.getProperties().containsKey(RESOURCE_LOADER)) {
properties.setProperty(RESOURCE_LOADER, "xwiki");
properties.setProperty(RESOURCE_LOADER_CLASS, XWikiWebappResourceLoader.class.getName());
}
if (xcontext != null && xcontext.getWiki() != null) {
// Note: if you don't want any template to be used set the property named
// xwiki.render.velocity.macrolist to an empty string value.
String macroList = xcontext.getWiki().Param("xwiki.render.velocity.macrolist");
if (macroList == null) {
macroList = "/templates/macros.vm";
}
properties.put(RuntimeConstants.VM_LIBRARY, macroList);
}
velocityEngine = this.velocityFactory.createVelocityEngine(cacheKey, properties);
if (template != null) {
// template by default
try {
final VelocityEngine finalVelocityEngine = velocityEngine;
this.authorExecutor.call(() -> {
finalVelocityEngine.evaluate(new VelocityContext(), NullWriter.NULL_WRITER, "", template.getContent().getContent());
return null;
}, template.getContent().getAuthorReference());
} catch (Exception e) {
this.logger.error("Failed to evaluate macros templates [{}]", template.getPath(), e);
}
}
}
}
}
return velocityEngine;
}
use of org.apache.velocity.VelocityContext in project xwiki-platform by xwiki.
the class MailSenderPlugin method sendMailFromTemplate.
/**
* Uses an XWiki document to build the message subject and context, based on variables stored in the
* VelocityContext. Sends the email.
*
* @param templateDocFullName Full name of the template to be used (example: XWiki.MyEmailTemplate). The template
* needs to have an XWiki.Email object attached
* @param from Email sender
* @param to Email recipient
* @param cc Email Carbon Copy
* @param bcc Email Hidden Carbon Copy
* @param language Language of the email
* @param vcontext Velocity context passed to the velocity renderer
* @return True if the email has been sent
*/
public int sendMailFromTemplate(String templateDocFullName, String from, String to, String cc, String bcc, String language, VelocityContext vcontext, XWikiContext context) throws XWikiException {
XWikiURLFactory originalURLFactory = context.getURLFactory();
Locale originalLocale = context.getLocale();
try {
context.setURLFactory(new ExternalServletURLFactory(context));
context.setLocale(LocaleUtils.toLocale(language));
VelocityContext updatedVelocityContext = prepareVelocityContext(from, to, cc, bcc, vcontext, context);
XWiki xwiki = context.getWiki();
XWikiDocument doc = xwiki.getDocument(templateDocFullName, context);
Document docApi = new Document(doc, context);
BaseObject obj = doc.getObject(EMAIL_XWIKI_CLASS_NAME, "language", language);
if (obj == null) {
obj = doc.getObject(EMAIL_XWIKI_CLASS_NAME, "language", "en");
}
if (obj == null) {
LOGGER.error("No mail object found in the document " + templateDocFullName);
return ERROR_TEMPLATE_EMAIL_OBJECT_NOT_FOUND;
}
String subjectContent = obj.getStringValue("subject");
String txtContent = obj.getStringValue("text");
String htmlContent = obj.getStringValue("html");
String subject = evaluate(subjectContent, templateDocFullName, updatedVelocityContext, context);
String msg = evaluate(txtContent, templateDocFullName, updatedVelocityContext, context);
String html = evaluate(htmlContent, templateDocFullName, updatedVelocityContext, context);
Mail mail = new Mail();
mail.setFrom((String) updatedVelocityContext.get("from.address"));
mail.setTo((String) updatedVelocityContext.get("to.address"));
mail.setCc((String) updatedVelocityContext.get("to.cc"));
mail.setBcc((String) updatedVelocityContext.get("to.bcc"));
mail.setSubject(subject);
mail.setTextPart(msg);
mail.setHtmlPart(html);
mail.setAttachments(docApi.getAttachmentList());
try {
sendMail(mail, context);
return 0;
} catch (Exception e) {
LOGGER.error("sendEmailFromTemplate: " + templateDocFullName + " vcontext: " + updatedVelocityContext, e);
return ERROR;
}
} finally {
context.setURLFactory(originalURLFactory);
context.setLocale(originalLocale);
}
}
use of org.apache.velocity.VelocityContext in project xwiki-platform by xwiki.
the class MailSenderPlugin method prepareVelocityContext.
/**
* Prepares a Mail Velocity context based on a map of parameters
*
* @param fromAddr Mail from
* @param toAddr Mail to
* @param ccAddr Mail cc
* @param bccAddr Mail bcc
* @param parameters variables to be passed to the velocity context
* @return The prepared context
*/
public VelocityContext prepareVelocityContext(String fromAddr, String toAddr, String ccAddr, String bccAddr, Map<String, Object> parameters, XWikiContext context) {
VelocityManager velocityManager = Utils.getComponent(VelocityManager.class);
VelocityContext vcontext = new VelocityContext(velocityManager.getVelocityContext());
if (parameters != null) {
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
vcontext.put(entry.getKey(), entry.getValue());
}
}
return vcontext;
}
use of org.apache.velocity.VelocityContext in project xwiki-platform by xwiki.
the class XWikiAction method execute.
public ActionForward execute(XWikiContext context) throws Exception {
MonitorPlugin monitor = null;
FileUploadPlugin fileupload = null;
DefaultJobProgress actionProgress = null;
ObservationManager om = Utils.getComponent(ObservationManager.class);
Execution execution = Utils.getComponent(Execution.class);
String docName = "";
boolean debug = StringUtils.equals(context.getRequest().get("debug"), "true");
try {
String action = context.getAction();
// Start progress
if (debug && om != null && execution != null) {
actionProgress = new DefaultJobProgress(context.getURL().toExternalForm());
om.addListener(new WrappedThreadEventListener(actionProgress));
// Register the action progress in the context
ExecutionContext econtext = execution.getContext();
if (econtext != null) {
econtext.setProperty(XWikiAction.ACTION_PROGRESS, actionProgress);
}
}
getProgress().pushLevelProgress(2, this);
getProgress().startStep(this, "Get XWiki instance");
// Initialize context.getWiki() with the main wiki
XWiki xwiki;
// Verify that the requested wiki exists
try {
xwiki = XWiki.getXWiki(this.waitForXWikiInitialization, context);
// If XWiki is still initializing display initialization template
if (xwiki == null) {
// Display initialization template
renderInit(context);
// Initialization template has been displayed, stop here.
return null;
}
} catch (XWikiException e) {
// redirects. If there are none, then we display the specific error template.
if (e.getCode() == XWikiException.ERROR_XWIKI_DOES_NOT_EXIST) {
xwiki = XWiki.getMainXWiki(context);
// Initialize the url factory
XWikiURLFactory urlf = xwiki.getURLFactoryService().createURLFactory(context.getMode(), context);
context.setURLFactory(urlf);
// Initialize the velocity context and its bindings so that it may be used in the velocity templates
// that we
// are parsing below.
VelocityManager velocityManager = Utils.getComponent(VelocityManager.class);
VelocityContext vcontext = velocityManager.getVelocityContext();
if (!sendGlobalRedirect(context.getResponse(), context.getURL().toString(), context)) {
// Starting XWiki 5.0M2, 'xwiki.virtual.redirect' was removed. Warn users still using it.
if (!StringUtils.isEmpty(context.getWiki().Param("xwiki.virtual.redirect"))) {
LOGGER.warn(String.format("%s %s", "'xwiki.virtual.redirect' is no longer supported.", "Please update your configuration and/or see XWIKI-8914 for more details."));
}
// Display the error template only for actions that are not ignored
if (!ACTIONS_IGNORED_WHEN_WIKI_DOES_NOT_EXIST.contains(action)) {
// Add localization resources to the context
xwiki.prepareResources(context);
// Set the main home page in the main space of the main wiki as the current requested entity
// since we cannot set the non existing one as it would generate errors obviously...
EntityReferenceValueProvider valueProvider = Utils.getComponent(EntityReferenceValueProvider.class);
xwiki.setPhonyDocument(new DocumentReference(valueProvider.getDefaultValue(EntityType.WIKI), valueProvider.getDefaultValue(EntityType.SPACE), valueProvider.getDefaultValue(EntityType.DOCUMENT)), context, vcontext);
// Parse the error template
Utils.parseTemplate(context.getWiki().Param("xwiki.wiki_exception", "wikidoesnotexist"), context);
// Error template was displayed, stop here.
return null;
}
// At this point, we allow regular execution of the ignored action because even if the wiki
// does not exist, we still need to allow UI resources to be retrieved (from the filesystem
// and the main wiki) or our error template will not be rendered properly.
// Proceed with serving the main wiki
} else {
// Global redirect was executed, stop here.
return null;
}
} else {
LOGGER.error("Uncaught exception during XWiki initialisation:", e);
throw e;
}
}
// Send global redirection (if any)
if (sendGlobalRedirect(context.getResponse(), context.getURL().toString(), context)) {
return null;
}
XWikiURLFactory urlf = xwiki.getURLFactoryService().createURLFactory(context.getMode(), context);
context.setURLFactory(urlf);
// Handle ability to enter space URLs and convert them to page URLs (Nested Documents)
if (redirectSpaceURLs(action, urlf, xwiki, context)) {
return null;
}
String sajax = context.getRequest().get("ajax");
boolean ajax = false;
if (sajax != null && !sajax.trim().equals("") && !sajax.equals("0")) {
ajax = true;
}
context.put("ajax", ajax);
if (monitor != null) {
monitor.startTimer("request");
}
getProgress().startStep(this, "Execute request");
VelocityManager velocityManager = Utils.getComponent(VelocityManager.class);
VelocityContext vcontext = velocityManager.getVelocityContext();
getProgress().pushLevelProgress(7, this);
boolean eventSent = false;
try {
getProgress().startStep(this, "Prepare documents and put them in the context");
// Prepare documents and put them in the context
if (!xwiki.prepareDocuments(context.getRequest(), context, vcontext)) {
return null;
}
// Start monitoring timer
monitor = (MonitorPlugin) xwiki.getPlugin("monitor", context);
if (monitor != null) {
monitor.startRequest("", context.getAction(), context.getURL());
monitor.startTimer("multipart");
}
getProgress().startStep(this, "Parses multipart");
// Parses multipart so that params in multipart are available for all actions
fileupload = Utils.handleMultipart(context.getRequest().getHttpServletRequest(), context);
if (monitor != null) {
monitor.endTimer("multipart");
}
if (monitor != null) {
monitor.setWikiPage(context.getDoc().getFullName());
}
getProgress().startStep(this, "Send [" + context.getAction() + "] action start event");
// and there won't be a need for the context.
try {
ActionExecutingEvent event = new ActionExecutingEvent(context.getAction());
om.notify(event, context.getDoc(), context);
eventSent = true;
if (event.isCanceled()) {
// TODO: do something special ?
return null;
}
} catch (Throwable ex) {
LOGGER.error("Cannot send action notifications for document [" + context.getDoc() + " using action [" + context.getAction() + "]", ex);
}
if (monitor != null) {
monitor.endTimer("prenotify");
}
// Call the Actions
getProgress().startStep(this, "Search and execute entity resource handler");
// Call the new Entity Resource Reference Handler.
ResourceReferenceHandler entityResourceReferenceHandler = Utils.getComponent(new DefaultParameterizedType(null, ResourceReferenceHandler.class, ResourceType.class), "bin");
ResourceReference resourceReference = Utils.getComponent(ResourceReferenceManager.class).getResourceReference();
try {
entityResourceReferenceHandler.handle(resourceReference, DefaultResourceReferenceHandlerChain.EMPTY);
// Don't let the old actions kick in!
return null;
} catch (NotFoundResourceHandlerException e) {
// No Entity Resource Action has been found. Don't do anything and let it go through
// so that the old Action system kicks in...
} catch (Throwable e) {
// Some real failure, log it since it's a problem but still allow the old Action system a chance
// to do something...
LOGGER.error("Failed to handle Action for Resource [{}]", resourceReference, e);
}
getProgress().startStep(this, "Execute action render");
// Handle the XWiki.RedirectClass object that can be attached to the current document
boolean hasRedirect = false;
if (handleRedirectObject) {
hasRedirect = handleRedirectObject(context);
}
// Then call the old Actions for backward compatibility (and because a lot of them have not been
// migrated to new Actions yet).
String renderResult = null;
XWikiDocument doc = context.getDoc();
docName = doc.getFullName();
if (!hasRedirect && action(context)) {
renderResult = render(context);
}
if (renderResult != null) {
if (doc.isNew() && "view".equals(context.getAction()) && !"recyclebin".equals(context.getRequest().get("viewer")) && !"children".equals(context.getRequest().get("viewer")) && !"siblings".equals(context.getRequest().get("viewer"))) {
String page = Utils.getPage(context.getRequest(), "docdoesnotexist");
getProgress().startStep(this, "Execute template [" + page + "]");
Utils.parseTemplate(page, context);
} else {
String page = Utils.getPage(context.getRequest(), renderResult);
getProgress().startStep(this, "Execute template [" + page + "]");
Utils.parseTemplate(page, !page.equals("direct"), context);
}
}
return null;
} catch (Throwable e) {
if (e instanceof IOException) {
e = new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_SEND_RESPONSE_EXCEPTION, "Exception while sending response", e);
}
if (!(e instanceof XWikiException)) {
e = new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_UNKNOWN, "Uncaught exception", e);
}
try {
XWikiException xex = (XWikiException) e;
if (xex.getCode() == XWikiException.ERROR_XWIKI_APP_SEND_RESPONSE_EXCEPTION) {
// Connection aborted from the client side, there's not much we can do on the server side. We
// simply ignore it.
LOGGER.debug("Connection aborted", e);
// We don't write any other message to the response, as the connection is broken, anyway.
return null;
} else if (xex.getCode() == XWikiException.ERROR_XWIKI_ACCESS_DENIED) {
Utils.parseTemplate(context.getWiki().Param("xwiki.access_exception", "accessdenied"), context);
return null;
} else if (xex.getCode() == XWikiException.ERROR_XWIKI_USER_INACTIVE) {
Utils.parseTemplate(context.getWiki().Param("xwiki.user_exception", "userinactive"), context);
return null;
} else if (xex.getCode() == XWikiException.ERROR_XWIKI_APP_ATTACHMENT_NOT_FOUND) {
context.put("message", "attachmentdoesnotexist");
Utils.parseTemplate(context.getWiki().Param("xwiki.attachment_exception", "attachmentdoesnotexist"), context);
return null;
} else if (xex.getCode() == XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION) {
vcontext.put("message", localizePlainOrKey("platform.core.invalidUrl"));
xwiki.setPhonyDocument(xwiki.getDefaultSpace(context) + "." + xwiki.getDefaultPage(context), context, vcontext);
context.getResponse().setStatus(HttpServletResponse.SC_BAD_REQUEST);
Utils.parseTemplate(context.getWiki().Param("xwiki.invalid_url_exception", "error"), context);
return null;
}
vcontext.put("exp", e);
if (LOGGER.isWarnEnabled()) {
// connection.
if (ExceptionUtils.getRootCauseMessage(e).equals("IOException: Broken pipe")) {
return null;
}
LOGGER.warn("Uncaught exception: " + e.getMessage(), e);
}
// If the request is an AJAX request, we don't return a whole HTML page, but just the exception
// inline.
String exceptionTemplate = ajax ? "exceptioninline" : "exception";
Utils.parseTemplate(Utils.getPage(context.getRequest(), exceptionTemplate), context);
return null;
} catch (XWikiException ex) {
if (ex.getCode() == XWikiException.ERROR_XWIKI_APP_SEND_RESPONSE_EXCEPTION) {
LOGGER.error("Connection aborted");
}
} catch (Exception e2) {
// I hope this never happens
LOGGER.error("Uncaught exceptions (inner): ", e);
LOGGER.error("Uncaught exceptions (outer): ", e2);
}
return null;
} finally {
// Let's make sure we have flushed content and closed
try {
context.getResponse().getWriter().flush();
} catch (Throwable e) {
// This might happen if the connection was closed, for example.
// If we can't flush, then there's nothing more we can send to the client.
}
if (monitor != null) {
monitor.endTimer("request");
monitor.startTimer("notify");
}
if (eventSent) {
// and there won't be a need for the context.
try {
om.notify(new ActionExecutedEvent(context.getAction()), context.getDoc(), context);
} catch (Throwable ex) {
LOGGER.error("Cannot send action notifications for document [" + docName + " using action [" + context.getAction() + "]", ex);
}
}
if (monitor != null) {
monitor.endTimer("notify");
}
getProgress().startStep(this, "Cleanup database connections");
// Make sure we cleanup database connections
// There could be cases where we have some
xwiki.getStore().cleanUp(context);
getProgress().popLevelProgress(this);
}
} finally {
// End request
if (monitor != null) {
monitor.endRequest();
}
// Stop progress
if (actionProgress != null) {
getProgress().popLevelProgress(this);
om.removeListener(actionProgress.getName());
}
if (fileupload != null) {
fileupload.cleanFileList(context);
}
}
}
Aggregations