/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xpn.xwiki.gwt.api.server;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.container.Container;
import org.xwiki.container.servlet.ServletContainerException;
import org.xwiki.container.servlet.ServletContainerInitializer;
import org.xwiki.context.Execution;
import org.xwiki.localization.ContextualLocalizationManager;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiLock;
import com.xpn.xwiki.gwt.api.client.Attachment;
import com.xpn.xwiki.gwt.api.client.Dictionary;
import com.xpn.xwiki.gwt.api.client.Document;
import com.xpn.xwiki.gwt.api.client.User;
import com.xpn.xwiki.gwt.api.client.VersionInfo;
import com.xpn.xwiki.gwt.api.client.XObject;
import com.xpn.xwiki.gwt.api.client.XWikiGWTException;
import com.xpn.xwiki.gwt.api.client.XWikiService;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.BaseProperty;
import com.xpn.xwiki.objects.PropertyInterface;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xpn.xwiki.objects.classes.ListClass;
import com.xpn.xwiki.user.api.XWikiUser;
import com.xpn.xwiki.web.Utils;
import com.xpn.xwiki.web.XWikiEngineContext;
import com.xpn.xwiki.web.XWikiMessageTool;
import com.xpn.xwiki.web.XWikiRequest;
import com.xpn.xwiki.web.XWikiResponse;
import com.xpn.xwiki.web.XWikiServletContext;
import com.xpn.xwiki.web.XWikiServletRequest;
import com.xpn.xwiki.web.XWikiServletResponse;
import com.xpn.xwiki.web.XWikiURLFactory;
public class XWikiServiceImpl extends RemoteServiceServlet implements XWikiService
{
private static final Logger LOGGER = LoggerFactory.getLogger(XWiki.class);
private ContextualLocalizationManager localization;
private ContextualLocalizationManager getLocalization()
{
if (this.localization == null) {
this.localization = Utils.getComponent(ContextualLocalizationManager.class);
}
return this.localization;
}
private String localizePlainOrKey(String key, Object... parameters)
{
return StringUtils.defaultString(getLocalization().getTranslationPlain(key, parameters), key);
}
/**
* We override the default processCall method in order to provide XWiki initialization before we handle the request.
* This allows us to initialize the XWiki Context and the new Container Objects (which are using ThreadLocal
* variables).
*
* @see RemoteServiceServlet#processCall(String)
*/
@Override
public String processCall(String payload) throws SerializationException
{
String result;
try {
initXWiki();
result = super.processCall(payload);
} catch (Exception e) {
throw new SerializationException("Failed to initialize XWiki GWT subsystem", e);
} finally {
// Perform cleanup here
cleanupContainerComponent();
}
return result;
}
/**
* Initialize XWiki Context and XWiki Container Objects.
*/
private void initXWiki() throws Exception
{
XWikiEngineContext engine = new XWikiServletContext(getServletContext());
XWikiRequest request = new XWikiServletRequest(getThreadLocalRequest());
XWikiResponse response = new XWikiServletResponse(getThreadLocalResponse());
XWikiContext context = Utils.prepareContext("", request, response, engine);
context.setMode(XWikiContext.MODE_GWT);
context.setWikiId("xwiki");
initializeContainerComponent(context);
XWiki xwiki = XWiki.getXWiki(context);
XWikiURLFactory urlf = xwiki.getURLFactoryService().createURLFactory(context.getMode(), context);
context.setURLFactory(urlf);
xwiki.prepareResources(context);
String username = "XWiki.XWikiGuest";
if (context.getMode() == XWikiContext.MODE_GWT_DEBUG) {
username = "XWiki.superadmin";
}
XWikiUser user = context.getWiki().checkAuth(context);
if (user != null) {
username = user.getUser();
}
context.setUser(username);
if (context.getDoc() == null) {
context.setDoc(new XWikiDocument("Fake", "Document"));
}
context.put("ajax", new Boolean(true));
}
private void initializeContainerComponent(XWikiContext context) throws ServletException
{
// Initialize the Container fields (request, response, session).
// Note that this is a bridge between the old core and the component architecture.
// In the new component architecture we use ThreadLocal to transport the request,
// response and session to components which require them.
ServletContainerInitializer containerInitializer = Utils.getComponent(ServletContainerInitializer.class);
try {
containerInitializer.initializeRequest(context.getRequest().getHttpServletRequest(), context);
containerInitializer.initializeResponse(context.getResponse());
containerInitializer.initializeSession(context.getRequest().getHttpServletRequest());
} catch (ServletContainerException e) {
throw new ServletException("Failed to initialize request/response or session", e);
}
}
private void cleanupContainerComponent()
{
Container container = Utils.getComponent(Container.class);
Execution execution = Utils.getComponent(Execution.class);
// We must ensure we clean the ThreadLocal variables located in the Container and Execution
// components as otherwise we will have a potential memory leak.
container.removeRequest();
container.removeResponse();
container.removeSession();
execution.removeContext();
}
/**
* Helper method to retrieve the {@link XWikiContext} from the {@link Execution} context.
*
* @return this execution's {@link XWikiContext}, set upon initialization
*/
protected XWikiContext getXWikiContext()
{
return (XWikiContext) Utils.getComponent(Execution.class).getContext().getProperty("xwikicontext");
}
protected XWikiGWTException getXWikiGWTException(Exception e)
{
// let's make sure we are informed
if (LOGGER.isErrorEnabled()) {
LOGGER.error("Unhandled exception on the server", e);
}
if (e instanceof XWikiGWTException) {
return (XWikiGWTException) e;
}
XWikiException exp;
if (e instanceof XWikiException)
exp = (XWikiException) e;
else
exp =
new XWikiException(XWikiException.MODULE_XWIKI_GWT_API, XWikiException.ERROR_XWIKI_UNKNOWN,
"Unknown GWT Exception", e);
return new XWikiGWTException(exp.getMessage(), exp.getFullMessage(), exp.getCode(), exp.getModule());
}
@Override
public Document getDocument(String fullName) throws XWikiGWTException
{
return getDocument(fullName, false, false, false, false);
}
@Override
public Document getDocument(String fullName, boolean full, boolean withRenderedContent) throws XWikiGWTException
{
return getDocument(fullName, full, false, false, withRenderedContent);
}
@Override
public String getUniquePageName(String space) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
return context.getWiki().getUniquePageName(space, context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public String getUniquePageName(String space, String pageName) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
return context.getWiki().getUniquePageName(space, pageName, context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Document getUniqueDocument(String space, String pageName) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
String fullName = context.getWiki().getUniquePageName(space, pageName, context);
return getDocument(fullName);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Document getUniqueDocument(String space) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
String fullName = context.getWiki().getUniquePageName(space, context);
return getDocument(space + "." + fullName);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Document getDocument(String fullName, boolean full, boolean viewDisplayers, boolean editDisplayers)
throws XWikiGWTException
{
return getDocument(fullName, full, viewDisplayers, editDisplayers, false);
}
@Override
public Document getDocument(String fullName, boolean full, boolean viewDisplayers, boolean editDisplayers,
boolean withRenderedContent) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("view", context.getUser(), fullName, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
return newDocument(new Document(), doc, full, viewDisplayers, editDisplayers, withRenderedContent,
context);
} else {
return null;
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean deleteDocument(String docName) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("delete", context.getUser(), docName, context)) {
XWikiDocument doc = context.getWiki().getDocument(docName, context);
context.getWiki().deleteDocument(doc, context);
return Boolean.valueOf(true);
} else {
return Boolean.valueOf(false);
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public int deleteDocuments(String sql) throws XWikiGWTException
{
int nb = 0;
try {
XWikiContext context = getXWikiContext();
List list = context.getWiki().getStore().searchDocumentsNames(sql, context);
if (list == null || list.isEmpty()) {
return nb;
}
for (int i = 0; i < list.size(); i++) {
if (context.getWiki().getRightService()
.hasAccessLevel("delete", context.getUser(), (String) list.get(i), context) == true) {
XWikiDocument doc = context.getWiki().getDocument((String) list.get(i), context);
context.getWiki().deleteDocument(doc, context);
nb++;
}
}
return nb;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public User getUser() throws XWikiGWTException
{
try {
return getUser(getXWikiContext().getUser());
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public User getUser(String fullName) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("view", context.getUser(), fullName, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
return newUser(new User(), doc, context);
} else {
return null;
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public User[] getUserList(int nb, int start) throws XWikiGWTException
{
User[] users = new User[nb];
try {
XWikiContext context = getXWikiContext();
List list =
searchDocuments(",BaseObject as obj where doc.fullName=obj.name and obj.className='XWiki.XWikiUsers'",
nb, start, context);
if (list == null)
return new User[0];
for (int i = 0; i < list.size(); i++) {
String username = (String) list.get(i);
XWikiDocument userdoc = context.getWiki().getDocument(username, context);
users[i] = newUser(new User(), userdoc, context);
}
return users;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public List searchDocuments(String sql, int nb, int start) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
return searchDocuments(sql, nb, start, context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public List getDocuments(String sql, int nb, int start) throws XWikiGWTException
{
return getDocuments(sql, nb, start, false);
}
@Override
public List getDocuments(String sql, int nb, int start, boolean full) throws XWikiGWTException
{
return getDocuments(sql, nb, start, full, false, false);
}
@Override
public List getDocuments(String sql, int nb, int start, boolean full, boolean viewDisplayers, boolean editDisplayers)
throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
return getDocuments(sql, nb, start, full, viewDisplayers, editDisplayers, false, context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public boolean updateProperty(String docname, String className, String propertyname, String value)
throws XWikiGWTException
{
XWikiContext context = null;
try {
context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), docname, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(docname, context);
BaseObject bobject = doc.getObject(className);
if (bobject == null) {
bobject = new BaseObject();
doc.addObject(className, bobject);
}
bobject.setName(doc.getFullName());
bobject.setClassName(className);
bobject.set(propertyname, value, context);
doc.setMetaDataDirty(true);
doc.setAuthor(context.getUser());
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.updateProperty"),
context);
return true;
} else
return false;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public boolean updateProperty(String docname, String className, String propertyname, int value)
throws XWikiGWTException
{
XWikiContext context = null;
try {
context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), docname, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(docname, context);
doc.setIntValue(className, propertyname, value);
doc.setAuthor(context.getUser());
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.updateProperty"),
context);
return true;
} else
return false;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public boolean updateProperty(String docname, String className, String propertyname, List value)
throws XWikiGWTException
{
XWikiContext context = null;
try {
context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), docname, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(docname, context);
BaseClass bclass = context.getWiki().getClass(className, context);
ListClass lclass = (ListClass) ((bclass == null) ? null : bclass.get(propertyname));
BaseProperty prop = lclass.fromValue(value);
doc.setProperty(className, propertyname, prop);
doc.setAuthor(context.getUser());
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.updateProperty"),
context);
return true;
} else
return false;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
private List getDocuments(String sql, int nb, int start, boolean full, boolean viewDisplayers,
boolean editDisplayers, boolean withRenderedContent, XWikiContext context) throws XWikiGWTException
{
List newlist = new ArrayList();
try {
List list = context.getWiki().getStore().searchDocumentsNames(sql, nb, start, context);
if (list == null || list.isEmpty()) {
return newlist;
}
for (int i = 0; i < list.size(); i++) {
if (context.getWiki().getRightService()
.hasAccessLevel("view", context.getUser(), (String) list.get(i), context) == true) {
XWikiDocument doc = context.getWiki().getDocument((String) list.get(i), context);
Document apidoc =
newDocument(new Document(), doc, full, viewDisplayers, editDisplayers, withRenderedContent,
context);
newlist.add(apidoc);
}
}
return newlist;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
private List searchDocuments(String sql, int nb, int start, XWikiContext context) throws XWikiGWTException
{
List newlist = new ArrayList();
try {
List list = context.getWiki().getStore().searchDocumentsNames(sql, nb, start, context);
if (list == null || list.isEmpty()) {
return newlist;
}
for (int i = 0; i < list.size(); i++) {
if (context.getWiki().getRightService()
.hasAccessLevel("view", context.getUser(), (String) list.get(i), context) == true)
newlist.add(list.get(i));
}
return newlist;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public List getObjects(String sql, String className, int nb, int start) throws XWikiGWTException
{
List docs = getDocuments(sql, nb, start, true);
List objects = new ArrayList();
Iterator it = docs.iterator();
while (it.hasNext()) {
Document doc = (Document) it.next();
List docObjs = doc.getObjects(className);
if (docObjs != null)
objects.addAll(docObjs);
}
return objects;
}
@Override
public XObject getFirstObject(String sql, String className) throws XWikiGWTException
{
List objs = getObjects(sql, className, 1, 0);
if (objs != null && objs.size() > 0)
return (XObject) objs.get(0);
return null;
}
public XObject addObject(XWikiDocument doc, String className) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
int index = doc.createNewObject(className, context);
return newObject(new XObject(), doc.getObject(className, index), false, false, context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public XObject addObject(String fullName, String className) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), fullName, context)) {
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
XObject obj = addObject(doc, className);
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.updateProperty"),
context);
return obj;
}
return null;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public List addObject(String fullName, List classesName) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
Iterator it = classesName.iterator();
List objs = new ArrayList();
while (it.hasNext()) {
objs.add(addObject(doc, (String) it.next()));
}
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.addObject"), context);
return objs;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public boolean addObject(String docname, XObject xobject) throws XWikiGWTException
{
XWikiContext context = null;
try {
context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), docname, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(docname, context);
BaseObject newObject = doc.newObject(xobject.getClassName(), context);
mergeObject(xobject, newObject, context);
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.addObject"), context);
return true;
} else
return false;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
/**
* save only the content of a document TODO manage translations
*
* @param fullName
* @param content
* @return
*/
@Override
public Boolean saveDocumentContent(String fullName, String content) throws XWikiGWTException
{
return saveDocumentContent(fullName, content, null);
}
/**
* save only the content of a document TODO manage translations
*
* @param fullName
* @param content
* @return
*/
public Boolean saveDocumentContent(String fullName, String content, String comment) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), fullName, context)) {
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
doc.setContent(content);
doc.setAuthor(context.getUser());
if (doc.isNew())
doc.setCreator(context.getUser());
context.getWiki().saveDocument(doc,
(comment == null) ? localizePlainOrKey("core.comment.updateContent") : comment, context);
return Boolean.valueOf(true);
} else {
return Boolean.valueOf(false);
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean saveObject(XObject object) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService()
.hasAccessLevel("edit", context.getUser(), object.getName(), context)) {
XWikiDocument doc = context.getWiki().getDocument(object.getName(), context);
BaseObject bObject =
newBaseObject(doc.getObject(object.getClassName(), object.getNumber()), object, context);
doc.setObject(object.getClassName(), object.getNumber(), bObject);
doc.setAuthor(context.getUser());
if (doc.isNew())
doc.setCreator(context.getUser());
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.updateObject"), context);
return Boolean.valueOf(true);
} else {
return Boolean.valueOf(false);
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean deleteObject(XObject object) throws XWikiGWTException
{
return deleteObject(object.getName(), object.getClassName(), object.getNumber());
}
@Override
public Boolean deleteObject(String docName, String className, int number) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), docName, context)) {
XWikiDocument doc = context.getWiki().getDocument(docName, context);
BaseObject bObj = doc.getObject(className, number);
if (!doc.removeObject(bObj))
return Boolean.valueOf(false);
doc.setAuthor(context.getUser());
if (doc.isNew())
doc.setCreator(context.getUser());
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.deleteObject"), context);
return Boolean.valueOf(true);
} else {
return Boolean.valueOf(false);
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean saveObjects(List objects) throws XWikiGWTException
{
Iterator it = objects.iterator();
boolean error = false;
while (it.hasNext()) {
error |= !saveObject((XObject) it.next()).booleanValue();
}
return Boolean.valueOf(!error);
}
/**
* return true if can be locked return null in case of an error return false in all the other cases
*
* @param fullName
* @param force
* @return
*/
@Override
public Boolean lockDocument(String fullName, boolean force) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
if (context.getWiki().getRightService().hasAccessLevel("edit", context.getUser(), fullName, context)) {
/* Setup a lock */
XWikiLock lock = doc.getLock(context);
if ((lock == null) || (lock.getUserName().equals(context.getUser())) || force) {
if (lock != null)
doc.removeLock(context);
doc.setLock(context.getUser(), context);
return Boolean.valueOf(true);
} else
return Boolean.valueOf(false);
} else
return Boolean.valueOf(false);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public void unlockDocument(String fullName) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
XWikiLock lock = doc.getLock(context);
if (lock != null)
doc.removeLock(context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean isLastDocumentVersion(String fullName, String version) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
return Boolean.valueOf(context.getWiki().getDocument(fullName, context).getVersion().equals(version));
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public String getLoginURL() throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
return context.getWiki().getDocument("XWiki.XWikiLogin", context).getExternalURL("login", context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public String login(String username, String password, boolean rememberme) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
XWikiUser user =
context.getWiki().getAuthService().checkAuth(username, password, rememberme ? "yes" : "no", context);
if (user == null)
return "XWiki.XWikiGuest";
else
return user.getUser();
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public boolean addComment(String docname, String message) throws XWikiGWTException
{
XWikiContext context = null;
try {
context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("comment", context.getUser(), docname, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(docname, context);
BaseObject newObject = doc.newObject("XWiki.XWikiComments", context);
newObject.set("author", context.getUser(), context);
newObject.set("date", new Date(), context);
newObject.set("comment", message, context);
doc.setContentDirty(false); // consider comments not being content
context.getWiki().saveDocument(doc, localizePlainOrKey("core.comment.addComment"), context);
return true;
} else
return false;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public List customQuery(String queryPage) throws XWikiGWTException
{
return customQuery(queryPage, null, 0, 0);
}
@Override
public List customQuery(String queryPage, Map params) throws XWikiGWTException
{
return customQuery(queryPage, params, 0, 0);
}
@Override
public List customQuery(String queryPage, int nb, int start) throws XWikiGWTException
{
return customQuery(queryPage, null, nb, start);
}
@Override
public List customQuery(String queryPage, Map params, int nb, int start) throws XWikiGWTException
{
List newlist = new ArrayList();
try {
XWikiContext context = getXWikiContext();
XWikiDocument queryDoc = context.getWiki().getDocument(queryPage, context);
if (context.getWiki().getRightService().hasProgrammingRights(queryDoc, context)) {
if (params != null) {
XWikiRequestWrapper srw = new XWikiRequestWrapper(context.getRequest());
Iterator it = params.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
Object value = params.get(key);
if (value instanceof String) {
// we clean params so that they cannot close a string
params.put(key, ((String) value).replaceAll("'", ""));
} else {
params.remove(key);
}
}
srw.setParameterMap(params);
context.setRequest(srw);
}
List list =
context.getWiki().getStore().search(queryDoc.getRenderedContent(context), nb, start, context);
for (int i = 0; i < list.size(); i++) {
Object[] item = (Object[]) list.get(i);
List itemlist = new ArrayList();
for (int j = 0; j < item.length; j++) {
itemlist.add(item[j]);
}
newlist.add(itemlist);
}
return newlist;
}
return null;
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
protected User newUser(User user, XWikiDocument xdoc, XWikiContext context) throws XWikiGWTException
{
newDocument(user, xdoc, context);
user.setFirstName(xdoc.getStringValue("XWiki.XWikiUsers", "first_name"));
user.setLastName(xdoc.getStringValue("XWiki.XWikiUsers", "last_name"));
user.setEmail(xdoc.getStringValue("XWiki.XWikiUsers", "email"));
XWiki xwiki = context.getWiki();
user.setAdmin(xwiki.getRightService().hasAdminRights(context));
return user;
}
protected Document newDocument(Document doc, XWikiDocument xdoc, XWikiContext context) throws XWikiGWTException
{
return newDocument(doc, xdoc, false, context);
}
protected Document newDocument(Document doc, XWikiDocument xdoc, boolean withObjects, XWikiContext context)
throws XWikiGWTException
{
return newDocument(doc, xdoc, withObjects, false, false, false, context);
}
public boolean hasAccessLevel(String level, String fullName, XWikiContext context) throws XWikiGWTException
{
try {
return getXWikiContext().getWiki().getRightService()
.hasAccessLevel(level, context.getUser(), fullName, context);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
protected void assertEditRight(XWikiDocument doc, XWikiContext context) throws XWikiGWTException, XWikiException
{
if (context.getMode() == XWikiContext.MODE_GWT_DEBUG)
return;
if (!hasAccessLevel("edit", doc.getFullName(), context))
raiseRightException(context);
}
protected void assertViewRight(String fullName, XWikiContext context) throws XWikiGWTException, XWikiException
{
if (context.getMode() == XWikiContext.MODE_GWT_DEBUG)
return;
if (!hasAccessLevel("view", fullName, context))
raiseRightException(context);
}
protected void raiseRightException(XWikiContext context) throws XWikiException
{
if (context.getUser().equals("XWiki.XWikiGuest")) {
throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
XWikiException.ERROR_XWIKI_ACCESS_TOKEN_INVALID, "User needs to be logged-in");
} else
throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS, XWikiException.ERROR_XWIKI_ACCESS_DENIED,
"User needs appropriate rights");
}
protected void assertViewRight(XWikiDocument doc, XWikiContext context) throws XWikiGWTException, XWikiException
{
assertViewRight(doc.getFullName(), context);
}
protected Document newDocument(Document doc, XWikiDocument xdoc, boolean withObjects, boolean withViewDisplayers,
boolean withEditDisplayers, boolean withRenderedContent, XWikiContext context) throws XWikiGWTException
{
doc.setId(xdoc.getId());
doc.setTitle(xdoc.getTitle());
doc.setFullName(xdoc.getFullName());
doc.setParent(xdoc.getParent());
doc.setSpace(xdoc.getSpace());
doc.setName(xdoc.getName());
doc.setContent(xdoc.getContent());
doc.setMeta(xdoc.getMeta());
doc.setFormat(xdoc.getFormat());
doc.setCreator(xdoc.getCreator());
doc.setAuthor(xdoc.getAuthor());
doc.setContentAuthor(xdoc.getContentAuthor());
doc.setCustomClass(xdoc.getCustomClass());
doc.setVersion(xdoc.getVersion());
doc.setContentUpdateDate(xdoc.getContentUpdateDate().getTime());
doc.setDate(xdoc.getDate().getTime());
doc.setCreationDate(xdoc.getCreationDate().getTime());
doc.setMostRecent(xdoc.isMostRecent());
doc.setNew(xdoc.isNew());
doc.setTemplate(xdoc.getTemplate());
doc.setLanguage(xdoc.getLanguage());
doc.setDefaultLanguage(xdoc.getDefaultLanguage());
doc.setTranslation(xdoc.getTranslation());
doc.setComment(xdoc.getComment());
List comments = xdoc.getComments();
doc.setCommentsNumber((comments == null) ? 0 : comments.size());
doc.setUploadURL(xdoc.getExternalURL("upload", "ajax=1", context)); // "ajax=1"
doc.setViewURL(xdoc.getExternalURL("view", context));
try {
doc.setSaveURL(context.getWiki().getExternalURL(xdoc.getFullName(), "save", "ajax=1", context)); // ,
// "ajax=1"
} catch (Exception e) {
throw getXWikiGWTException(e);
}
doc.setHasElement(xdoc.getElements());
try {
doc.setEditRight(context.getWiki().getRightService()
.hasAccessLevel("edit", context.getUser(), xdoc.getFullName(), context));
} catch (Exception e) {
throw getXWikiGWTException(e);
}
try {
doc.setCommentRight(context.getWiki().getRightService()
.hasAccessLevel("comment", context.getUser(), xdoc.getFullName(), context));
} catch (Exception e) {
throw getXWikiGWTException(e);
}
if (withObjects) {
Iterator<List<BaseObject>> it = xdoc.getXObjects().values().iterator();
while (it.hasNext()) {
List<BaseObject> list = it.next();
for (int i = 0; i < list.size(); i++) {
BaseObject bobj = list.get(i);
if (bobj != null) {
XObject obj = newObject(new XObject(), bobj, withViewDisplayers, withEditDisplayers, context);
doc.addObject(bobj.getClassName(), obj);
}
}
}
}
if (xdoc.getAttachmentList() != null && xdoc.getAttachmentList().size() > 0) {
Iterator it = xdoc.getAttachmentList().iterator();
while (it.hasNext()) {
XWikiAttachment xAtt = (XWikiAttachment) it.next();
Attachment att = newAttachment(new Attachment(), xAtt, context);
doc.addAttachments(att);
}
}
if (withRenderedContent) {
try {
doc.setRenderedContent(xdoc.getRenderedContent(context));
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
return doc;
}
protected Attachment newAttachment(Attachment att, XWikiAttachment xAtt, XWikiContext context)
{
att.setAttDate(xAtt.getDate().getTime());
att.setAuthor(xAtt.getAuthor());
att.setFilename(xAtt.getFilename());
att.setId(xAtt.getId());
att.setImage(xAtt.isImage(context));
att.setMimeType(xAtt.getMimeType(context));
att.setLongSize(xAtt.getLongSize());
att.setDownloadUrl(context.getWiki().getExternalAttachmentURL(xAtt.getDoc().getFullName(), xAtt.getFilename(),
context));
return att;
}
protected XObject newObject(XObject xObject, BaseObject baseObject, boolean withViewDisplayers,
boolean withEditDisplayers, XWikiContext context)
{
xObject.setName(baseObject.getName());
xObject.setNumber(baseObject.getNumber());
xObject.setClassName(baseObject.getClassName());
String prefix = baseObject.getXClass(context).getName() + "_" + baseObject.getNumber() + "_";
Object[] propnames = baseObject.getXClass(context).getFieldList().toArray();
for (int i = 0; i < propnames.length; i++) {
String propname = ((PropertyInterface) propnames[i]).getName();
// TODO: this needs to be a param
if (!propname.equals("fullcontent")) {
try {
BaseProperty prop = (BaseProperty) baseObject.get(propname);
if (prop != null) {
Object value = prop.getValue();
if (value instanceof Date)
xObject.set(propname, new Date(((Date) prop.getValue()).getTime()));
else if (value instanceof List) {
List newlist = new ArrayList();
for (int j = 0; j < ((List) value).size(); j++) {
newlist.add(((List) value).get(j));
}
xObject.set(propname, newlist);
} else
xObject.set(propname, prop.getValue());
}
} catch (Exception e) {
}
try {
if (withViewDisplayers)
xObject.setViewProperty(propname, baseObject.displayView(propname, prefix, context));
} catch (Exception e) {
}
try {
if (withEditDisplayers) {
xObject.setEditProperty(propname, baseObject.displayEdit(propname, prefix, context));
xObject.setEditPropertyFieldName(propname, prefix + propname);
}
} catch (Exception e) {
}
}
}
return xObject;
}
protected void mergeObject(XObject xobject, BaseObject baseObject, XWikiContext context)
{
BaseClass bclass = baseObject.getXClass(context);
Object[] propnames = bclass.getPropertyNames();
for (int i = 0; i < propnames.length; i++) {
String propname = (String) propnames[i];
Object propdata = xobject.getProperty(propname);
baseObject.set(propname, propdata, context);
}
}
@Override
public String getDocumentContent(String fullName) throws XWikiGWTException
{
return getDocumentContent(fullName, false, null);
}
protected BaseObject newBaseObject(BaseObject baseObject, XObject xObject, XWikiContext context)
throws XWikiException
{
if (baseObject == null) {
baseObject = (BaseObject) context.getWiki().getClass(xObject.getClassName(), context).newObject(context);
baseObject.setName(xObject.getName());
baseObject.setNumber(xObject.getNumber());
}
Object[] propnames = xObject.getPropertyNames().toArray();
for (int i = 0; i < propnames.length; i++) {
String propname = (String) propnames[i];
try {
// TODO will not work for a date
baseObject.set(propname, xObject.get(propname), context);
} catch (Exception e) {
}
}
return baseObject;
}
@Override
public String getDocumentContent(String fullName, boolean rendered) throws XWikiGWTException
{
return getDocumentContent(fullName, rendered, null);
}
@Override
public String getDocumentContent(String fullName, boolean rendered, Map params) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("view", context.getUser(), fullName, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
context.setDoc(doc);
if (!rendered)
return doc.getContent();
else {
XWikiRequestWrapper srw = new XWikiRequestWrapper(context.getRequest());
srw.setParameterMap(params);
context.setRequest(srw);
return doc.getRenderedContent(context);
}
} else {
return null;
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
// get version history of a document
@Override
public List getDocumentVersions(String fullName, int nb, int start) throws XWikiGWTException
{
try {
List versionsList = new ArrayList();
XWikiContext context = getXWikiContext();
if (context.getWiki().getRightService().hasAccessLevel("view", context.getUser(), fullName, context) == true) {
XWikiDocument doc = context.getWiki().getDocument(fullName, context);
String[] versions =
(nb == 0) ? doc.getRecentRevisions(0, context) : doc.getRecentRevisions(nb + start, context);
int nbVersions = (nb == 0) ? (versions.length - start) : nb;
for (int i = 0; i < nbVersions; i++) {
int j = i + start;
if (j < versions.length) {
String version = versions[j];
XWikiDocument vdoc = null;
try {
vdoc = context.getWiki().getDocument(doc, version, context);
} catch (Exception e) {
}
if (vdoc != null) {
String authorLink = context.getWiki().getURL(vdoc.getAuthor(), "view", context);
String author = context.getWiki().getLocalUserName(vdoc.getAuthor(), null, false, context);
versionsList.add(new VersionInfo(version, vdoc.getDate().getTime(), author, authorLink,
vdoc.getComment()));
} else {
versionsList.add(new VersionInfo(version, 0, "?", "?", "?"));
}
} else {
break;
}
}
return versionsList;
} else {
return versionsList;
}
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public void logJSError(Map infos)
{
LOGGER.warn("[GWT-JS] useragent:" + infos.get("useragent") + "\n" + "module:" + infos.get("module") + "\n");
// + "stacktrace" + infos.get("stacktrace"));
}
@Override
public Dictionary getTranslation(String translationPage, String locale) throws XWikiGWTException
{
try {
XWikiContext context = getXWikiContext();
XWikiMessageTool msg = context.getMessageTool();
String defaultLanguage = context.getWiki().getDefaultLanguage(context);
// Get the translated version of the translation page document with the default language one
List docBundles = msg.getDocumentBundles(translationPage, defaultLanguage);
Properties properties = new Properties();
// loop backwards to have the default language updated first and then overwritten with the current language
for (int i = 0; i < docBundles.size(); i++) {
Properties encproperties =
(msg == null) ? null : msg.getDocumentBundleProperties((XWikiDocument) docBundles.get(docBundles
.size() - i - 1));
if (encproperties != null) {
properties.putAll(encproperties);
}
}
return new Dictionary(properties);
} catch (Exception e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean hasAccessLevel(String level, String docName) throws XWikiGWTException
{
XWikiContext context = getXWikiContext();
try {
return Boolean.valueOf(context.getWiki().getRightService()
.hasAccessLevel(level, context.getUser(), docName, context));
} catch (XWikiException e) {
throw getXWikiGWTException(e);
}
}
@Override
public Boolean hasAccessLevel(String level, String username, String docName) throws XWikiGWTException
{
try {
return Boolean.valueOf(getXWikiContext().getWiki().getRightService()
.hasAccessLevel(level, username, docName, getXWikiContext()));
} catch (XWikiException e) {
throw getXWikiGWTException(e);
}
}
}