package com.celements.web.service; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Locale; import javax.inject.Singleton; import javax.servlet.http.Cookie; import org.apache.commons.lang.StringUtils; import org.apache.velocity.VelocityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.Requirement; import org.xwiki.context.Execution; import org.xwiki.context.ExecutionContext; import org.xwiki.model.reference.DocumentReference; import com.celements.pagetype.PageType; import com.celements.pagetype.PageTypeReference; import com.celements.pagetype.cmd.PageTypeCommand; import com.celements.pagetype.service.IPageTypeResolverRole; import com.celements.pagetype.service.IPageTypeRole; import com.celements.web.plugin.cmd.CheckClassesCommand; import com.xpn.xwiki.XWiki; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.api.Document; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.objects.BaseObject; import com.xpn.xwiki.objects.BaseProperty; import com.xpn.xwiki.util.Util; import com.xpn.xwiki.web.XWikiRequest; /** * TODO implement VelocityContextInitializer role --> maybe XWiki overwrites later some * vcontext variables ($language, $doc, $tdoc) * * @author fabian */ @Component @Singleton public class PrepareVelocityContextService implements IPrepareVelocityContext { private static Logger _LOGGER = LoggerFactory.getLogger(PrepareVelocityContextService.class); private String _CEL_PREPARE_VELOCITY_COUNTER = "celPrepareVelocityCounter"; private String _CEL_PREPARE_VELOCITY_TOTALTIME = "celPrepareVelocityTotelTime"; @Requirement Execution execution; @Requirement IWebUtilsService webUtilsService; @Requirement IPageTypeResolverRole pageTypeResolver; @Requirement IPageTypeRole pageTypeService; private XWikiContext getContext() { return (XWikiContext) getExecContext().getProperty("xwikicontext"); } private ExecutionContext getExecContext() { return execution.getContext(); } @Override public void prepareVelocityContext(VelocityContext vcontext) { Integer count = 0; if (getExecContext().getProperty(_CEL_PREPARE_VELOCITY_COUNTER) != null) { count = (Integer) getExecContext().getProperty(_CEL_PREPARE_VELOCITY_COUNTER); } count = count + 1; long startMillis = System.currentTimeMillis(); _LOGGER.debug("prepareVelocityContext [" + count + "]: with vcontext [" + vcontext + "]."); fixLanguagePreference(vcontext); _LOGGER.trace("prepareVelocityContext [" + count + "]: after fixLanguagePreference."); fixTdocForInvalidLanguage(vcontext); _LOGGER.trace("prepareVelocityContext [" + count + "]: after fixTdocForInvalidLanguage."); initCelementsVelocity(vcontext); _LOGGER.trace("prepareVelocityContext [" + count + "]: after initCelementsVelocity."); initPanelsVelocity(vcontext); _LOGGER.trace("prepareVelocityContext [" + count + "]: after initCelementsVelocity."); getExecContext().setProperty(_CEL_PREPARE_VELOCITY_COUNTER, count); if (_LOGGER.isInfoEnabled()) { long endMillis = System.currentTimeMillis(); long timeUsed = endMillis - startMillis; Long totalTimeUsed = 0L; if (getExecContext().getProperty(_CEL_PREPARE_VELOCITY_TOTALTIME) != null) { totalTimeUsed = (Long) getExecContext().getProperty(_CEL_PREPARE_VELOCITY_TOTALTIME); } totalTimeUsed += timeUsed; getExecContext().setProperty(_CEL_PREPARE_VELOCITY_TOTALTIME, totalTimeUsed); _LOGGER.info("prepareVelocityContext [" + count + "]: with vcontext [" + vcontext + "] finished in [" + timeUsed + "], total time [" + totalTimeUsed + "]."); } } /** * @param context * @deprecated instead use prepareVelocityContext(VelocityContext) */ @Override @Deprecated public void prepareVelocityContext(XWikiContext context) { if (context != null) { prepareVelocityContext((VelocityContext) context.get("vcontext")); } } void fixLanguagePreference(VelocityContext vcontext) { String langPref = getLanguagePreference(getContext()); getContext().setLanguage(langPref); if (vcontext != null) { vcontext.put("language", langPref); } } void initPanelsVelocity(VelocityContext vcontext) { if (vcontext != null) { if (!vcontext.containsKey("rightPanels")) { _LOGGER.debug("setting rightPanels in vcontext: " + getRightPanels()); vcontext.put("rightPanels", getRightPanels()); } if (!vcontext.containsKey("leftPanels")) { _LOGGER.debug("setting leftPanels in vcontext: " + getLeftPanels()); vcontext.put("leftPanels", getLeftPanels()); } if (!vcontext.containsKey("showRightPanels")) { vcontext.put("showRightPanels", Integer.toString(showRightPanels())); } if (!vcontext.containsKey("showLeftPanels")) { vcontext.put("showLeftPanels", Integer.toString(showLeftPanels())); } _LOGGER.debug("leftPanels [" + vcontext.get("leftPanels") + "] and rightPanels [" + vcontext.get("rightPanels") + "] after initPanelsVelocity."); } } void initCelementsVelocity(VelocityContext vcontext) { if ((vcontext != null) && (getContext().getWiki() != null)) { if (!vcontext.containsKey(getVelocityName())) { vcontext.put(getVelocityName(), getContext().getWiki().getPluginApi(getVelocityName(), getContext())); } if (!vcontext.containsKey("default_language")) { vcontext.put("default_language", webUtilsService.getDefaultLanguage()); } if (!vcontext.containsKey("langs")) { vcontext.put("langs", webUtilsService.getAllowedLanguages()); } if (!vcontext.containsKey("hasedit")) { try { if (getContext().getDoc() != null) { vcontext.put("hasedit", getContext().getWiki().getRightService().hasAccessLevel("edit", getContext().getUser(), getContext().getDoc().getFullName(), getContext())); } else { vcontext.put("hasedit", new Boolean(false)); } } catch (XWikiException exp) { _LOGGER.error("Failed to check edit Access Rights on " + getContext().getDoc().getDocumentReference(), exp); vcontext.put("hasedit", new Boolean(false)); } } if (!vcontext.containsKey("skin_doc")) { try { String skinDocName = getContext().getWiki().getSkin(getContext()); Document skinDoc = getContext().getWiki().getDocument( webUtilsService.resolveDocumentReference(skinDocName), getContext()).newDocument( getContext()); vcontext.put("skin_doc", skinDoc); } catch (XWikiException e) { _LOGGER.error("Failed to get skin_doc"); } } if (!vcontext.containsKey("isAdmin")) { vcontext.put("isAdmin", webUtilsService.isAdminUser()); } if (!vcontext.containsKey("isSuperAdmin")) { vcontext.put("isSuperAdmin", webUtilsService.isSuperAdminUser()); } if (!vcontext.containsKey("admin_language")) { vcontext.put("admin_language", webUtilsService.getAdminLanguage()); _LOGGER.debug("added admin_language to vcontext: " + webUtilsService.getAdminLanguage()); } if (!vcontext.containsKey("adminMsg")) { vcontext.put("adminMsg", webUtilsService.getAdminMessageTool()); } if (!vcontext.containsKey("celements2_skin")) { vcontext.put("celements2_skin", getCelementsSkinDoc(getContext())); } try { if (!vcontext.containsKey("celements2_baseurl") && (getContext().getURLFactory() != null)) { XWikiDocument celementsSkinXWikiDoc = getCelementsSkinXWikiDoc(getContext()); String celements2_baseurl = celementsSkinXWikiDoc.getURL("view", getContext()); if (celements2_baseurl.indexOf("/", 8) > 0) { vcontext.put("celements2_baseurl", celements2_baseurl.substring(0, celements2_baseurl.indexOf("/", 8))); } } } catch (XWikiException exp) { _LOGGER.error("failed to get CelementsSkin XWikiDocument.", exp); } if (!vcontext.containsKey("page_type")) { PageTypeReference pageTypeRef = pageTypeResolver.getPageTypeRefForCurrentDoc(); if (pageTypeRef != null) { vcontext.put("page_type", pageTypeRef.getConfigName()); } } else { _LOGGER.debug("initCelementsVelocity: page_type [{}] already available in context", vcontext.get("page_type")); } if (!vcontext.containsKey("user")) { vcontext.put("user", getContext().getUser()); } if (!vcontext.containsKey("isContentEditor")) { vcontext.put("isContentEditor", getContext().getWiki().getUser(getContext().getUser(), getContext()).isUserInGroup("XWiki.ContentEditorsGroup")); } if (!vcontext.containsKey("q")) { vcontext.put("q", "'"); } if (!vcontext.containsKey("Q")) { vcontext.put("Q", "\""); } if (!vcontext.containsKey("tinyMCE_width")) { vcontext.put("tinyMCE_width", getRTEwidth(getContext())); } } } String getRTEwidth(XWikiContext context) { int tinyMCEwidth = -1; String tinyMCEwidthStr = ""; if (getCelementsSkinDoc(context) != null) { BaseObject pageTypeObj = new PageTypeCommand().getPageTypeObj(context.getDoc(), context).getPageTypeProperties(context); if (pageTypeObj != null) { tinyMCEwidth = pageTypeObj.getIntValue("rte_width", -1); tinyMCEwidthStr = Integer.toString(tinyMCEwidth); } if (tinyMCEwidth < 0) { tinyMCEwidthStr = context.getWiki().getSpacePreference("editbox_width", context); if ((tinyMCEwidthStr != null) && !"".equals(tinyMCEwidthStr)) { tinyMCEwidth = Integer.parseInt(tinyMCEwidthStr); } } } if (tinyMCEwidth < 0) { tinyMCEwidth = 453; tinyMCEwidthStr = Integer.toString(tinyMCEwidth); } return tinyMCEwidthStr; } private Document getCelementsSkinDoc(XWikiContext context) { Document skinDoc = null; try { skinDoc = getCelementsSkinXWikiDoc(context).newDocument(context); } catch (XWikiException exp) { _LOGGER.error("Failed to load celements2_skin" + " (celements2web:XWiki.Celements2Skin) ", exp); } return skinDoc; } private XWikiDocument getCelementsSkinXWikiDoc(XWikiContext context) throws XWikiException { return context.getWiki().getDocument(new DocumentReference("celements2web", "XWiki", "Celements2Skin"), context); } @Override public int showRightPanels() { if (showRightPanelsBoolean(getContext()) && !getRightPanels().isEmpty()) { return 1; } else { return 0; } } private boolean showRightPanelsBoolean(XWikiContext context) { return showPanelByConfigName(context, "showRightPanels"); } @Override public int showLeftPanels() { if (showLeftPanelsBoolean(getContext()) && !getLeftPanels().isEmpty()) { return 1; } else { return 0; } } private boolean showLeftPanelsBoolean(XWikiContext context) { return showPanelByConfigName(context, "showLeftPanels"); } @Override public List<String> getRightPanels() { if (showRightPanelsBoolean(getContext())) { return Arrays.asList(getPanelString(getContext(), "rightPanels").split(",")); } else { return Collections.emptyList(); } } @Override public List<String> getLeftPanels() { if (showLeftPanelsBoolean(getContext())) { return Arrays.asList(getPanelString(getContext(), "leftPanels").split(",")); } else { return Collections.emptyList(); } } boolean showPanelByConfigName(XWikiContext context, String configName) { if (isPageShowPanelOverwrite(configName, context.getDoc())) { return (1 == getPagePanelObj(configName, context.getDoc()).getIntValue("show_panels")); } else if ((getPageTypeDoc(context) != null) && isPageShowPanelOverwrite(configName, getPageTypeDoc(context))) { boolean showPanels = (1 == getPagePanelObj(configName, getPageTypeDoc(context)).getIntValue( "show_panels")); _LOGGER.debug("using pagetype for panels " + configName + " -> " + showPanels); return showPanels; } else if (isSpaceOverwrite(context)) { boolean showPanels = "1".equals(context.getWiki().getSpacePreference(configName, getSpaceOverwrite(context), "0", context)); _LOGGER.debug("using spaceover webPrefs for panels " + configName + "," + getSpaceOverwrite( context) + " -> " + showPanels); return showPanels; } else if (isGlobalPref(context)) { boolean showPanels = ("1".equals(context.getWiki().getXWikiPreference(configName, context))); _LOGGER.debug("using globalPref for panels " + configName + " -> " + showPanels); return showPanels; } else if (context.getWiki() != null) { boolean showPanels = ("1".equals(context.getWiki().getSpacePreference(configName, context))); _LOGGER.debug("using webPrefs for panels " + configName + " -> " + showPanels); return showPanels; } return false; } XWikiDocument getPageTypeDoc(XWikiContext context) { if (context.getDoc() != null) { PageTypeReference pTRefForCurrDoc = pageTypeResolver.getPageTypeRefForCurrentDoc(); if (pTRefForCurrDoc != null) { try { DocumentReference pageTypeDocRef = new DocumentReference(context.getDatabase(), "PageTypes", pTRefForCurrDoc.getConfigName()); XWikiDocument pageTypeDoc = new PageType(pageTypeDocRef).getTemplateDocument( getContext()); _LOGGER.debug("getPageTypeDoc: pageTypeDoc=" + pageTypeDoc); return pageTypeDoc; } catch (XWikiException exp) { _LOGGER.error("Failed to getPageTypeDoc.", exp); } } else { _LOGGER.info("no pageType reference for current document found."); } } return null; } private BaseObject getPagePanelObj(String configName, XWikiDocument theDoc) { if (theDoc != null) { return theDoc.getObject(CheckClassesCommand.CLASS_PANEL_CONFIG_CLASS, "config_name", getPanelType(configName), false); } else { return null; } } private boolean isPageShowPanelOverwrite(String configName, XWikiDocument theDoc) { try { return ((getPagePanelObj(configName, theDoc) != null) && (((BaseProperty) getPagePanelObj( configName, theDoc).get("show_panels")).getValue() != null)); } catch (XWikiException exp) { _LOGGER.error("", exp); return false; } } private String getPanelType(String configName) { if ("showLeftPanels".equals(configName)) { return "leftPanels"; } else if ("showRightPanels".equals(configName)) { return "rightPanels"; } else { return configName; } } private boolean isSpaceOverwrite(XWikiContext context) { return ((getSpaceOverwrite(context) != null) && !"".equals(getSpaceOverwrite(context))); } private String getPanelString(XWikiContext context, String configName) { String panelsString = ""; if (isGlobalPref(context)) { panelsString = context.getWiki().getXWikiPreference(configName, context); } else if (isPagePanelsOverwrite(configName, context.getDoc())) { panelsString = getPagePanelObj(configName, context.getDoc()).getStringValue("panels"); } else if ((getPageTypeDoc(context) != null) && isPagePanelsOverwrite(configName, getPageTypeDoc(context))) { panelsString = getPagePanelObj(configName, getPageTypeDoc(context)).getStringValue("panels"); } else if (isSpaceOverwrite(context)) { panelsString = context.getWiki().getSpacePreference(configName, getSpaceOverwrite(context), "", context); } else { panelsString = context.getWiki().getUserPreference(configName, context); _LOGGER.debug("else with panels in userPreferences: " + panelsString); if ("".equals(panelsString)) { panelsString = context.getWiki().getSpacePreference(configName, context); _LOGGER.debug("else with panels in webPreferences: " + panelsString); } } _LOGGER.debug("panels for config " + configName + " ; " + panelsString); return panelsString; } private boolean isPagePanelsOverwrite(String configName, XWikiDocument theDoc) { return ((getPagePanelObj(configName, theDoc) != null) && (!"".equals(getPagePanelObj(configName, theDoc).getStringValue("panels")))); } private String getSpaceOverwrite(XWikiContext context) { if (context.getRequest() != null) { return context.getRequest().get("space"); } return ""; } private boolean isGlobalPref(XWikiContext context) { if ((context.getDoc() != null) && (context.getRequest() != null)) { return new DocumentReference(context.getDatabase(), "XWiki", "XWikiPreferences").equals( context.getDoc().getDocumentReference()) || "globaladmin".equals(context.getRequest().get( "editor")); } return false; } @Override public String getVelocityName() { return "celementsweb"; } /** * First try to find the current language in use from the XWiki context. If none is used * and if the wiki is not multilingual use the default language defined in the XWiki * preferences. If the wiki is multilingual try to get the language passed in the * request. If none was passed try to get it from a cookie. If no language cookie exists * then use the user default language and barring that use the browser's * "Accept-Language" header sent in HTTP request. If none is defined use the default * language. * * @return the language to use introduced in 2.18.0 because of a bug in xwiki 2.7.2 it * is fixed in unstable-xwiki4 YET celements allows default_language and * language change between spaces. XWiki does not! */ String getLanguagePreference(XWikiContext context) { _LOGGER.debug("getLanguagePreference: start " + context.getLanguage()); String language = context.getLanguage(); _LOGGER.debug("getLanguagePreference: isMultiLingual [" + context.getWiki().isMultiLingual( context) + "] defaultLanguage [" + webUtilsService.getDefaultLanguage() + "]."); // If the wiki is non multilingual then the language is the default // language. if (!context.getWiki().isMultiLingual(context)) { return webUtilsService.getDefaultLanguage(); } if (context.getRequest() != null) { try { language = getLanguageInRequestParam(); if (isValidLanguage(language)) { _LOGGER.debug("getLanguagePreference: found parameter language " + language); return language; } } catch (Exception e) { _LOGGER.error("Failed to get the language paramter from the request.", e); } // As no language parameter was passed in the request, try to get the // language to use from a cookie. try { language = getLanguageFromCookie(); if (isValidLanguage(language)) { _LOGGER.debug("getLanguagePreference: found cookie language " + language); return language; } } catch (Exception e) { _LOGGER.error("Failed to get the language from the cookie.", e); } } else { _LOGGER.info("getLanguagePreference: skip language parameter in request and" + " language cookie check, because request is null."); } _LOGGER.trace("getLanguagePreference: Next from the default user preference."); // Next from the default user preference try { language = getLanguageFromUserPreferences(); if (isValidLanguage(language)) { _LOGGER.debug("getLanguagePreference: found userpref language " + language); return language; } } catch (XWikiException e) { _LOGGER.error("Failed to get the default language from the user preferences.", e); } _LOGGER.trace("getLanguagePreference: Next from preferDefault? "); if (isConsiderBrowserAcceptLanguages()) { _LOGGER.trace("getLanguagePreference: Then from the navigator language setting."); // Then from the navigator language setting if (context.getRequest() != null) { language = getLanguageFromAcceptedHeaderLanguages(); if (isValidLanguage(language)) { _LOGGER.debug("getLanguagePreference: found accepted language " + language); return language; } } else { _LOGGER.info("getLanguagePreference: skip accept-language in request," + " because request is null."); } } else { _LOGGER.debug("getLanguagePreference: found preferDefault language " + language); } // Finally, use the default language from the global preferences. _LOGGER.debug("getLanguagePreference: use default language " + language); return webUtilsService.getDefaultLanguage(); } private boolean isValidLanguage(String language) { boolean isValidLanguage = (language != null) && !"".equals(language) && webUtilsService.getAllowedLanguages().contains(language); return isValidLanguage; } private String getLanguageFromAcceptedHeaderLanguages() { String language = ""; XWiki xwiki = getContext().getWiki(); String acceptHeader = getContext().getRequest().getHeader("Accept-Language"); // If the client didn't specify some languages, skip this phase if ((acceptHeader != null) && (!acceptHeader.equals(""))) { List<String> acceptedLanguages = getAcceptedLanguages(getContext().getRequest()); _LOGGER.debug("getLanguageFromAcceptedHeaderLanguages: getAcceptedLanguages " + acceptedLanguages); _LOGGER.debug("getLanguageFromAcceptedHeaderLanguages: forceSupported " + xwiki.Param( "xwiki.language.forceSupported", "0")); // We can force one of the configured languages to be accepted if (xwiki.Param("xwiki.language.forceSupported", "0").equals("1")) { List<String> available = webUtilsService.getAllowedLanguages(); _LOGGER.debug("getLanguageFromAcceptedHeaderLanguages: forceSupported lang " + " languages [" + Arrays.deepToString(available.toArray(new String[] {})) + "]."); // Filter only configured languages acceptedLanguages.retainAll(available); } _LOGGER.debug("getLanguageFromAcceptedHeaderLanguages: acceptedLanguages after " + acceptedLanguages); if (acceptedLanguages.size() > 0) { // Use the "most-preferred" language, as requested by the client. language = acceptedLanguages.get(0); } // If none of the languages requested by the client is acceptable, skip // to next // phase (use default language). } return language; } private boolean isConsiderBrowserAcceptLanguages() { XWiki xwiki = getContext().getWiki(); return !xwiki.Param("xwiki.language.preferDefault", "0").equals("1") && !xwiki.getSpacePreference("preferDefaultLanguage", "0", getContext()).equals("1"); } private String getLanguageFromUserPreferences() throws XWikiException { String language = null; String userFN = getContext().getUser(); XWikiDocument userdoc = null; userdoc = getContext().getWiki().getDocument(webUtilsService.resolveDocumentReference(userFN), getContext()); if (userdoc != null) { language = Util.normalizeLanguage(userdoc.getStringValue("XWiki.XWikiUsers", "default_language")); } return language; } private String getLanguageFromCookie() { // First we get the language from the cookie // !!! getUserPreferenceFromCookie throws NPE if request is NULL !!! return Util.normalizeLanguage(getContext().getWiki().getUserPreferenceFromCookie("language", getContext())); } /** * As the wiki is multilingual try to find the language to use from the request by * looking for a language parameter. If the language value is "default" use the default * language from the XWiki preferences settings. Otherwise set a cookie to remember the * language in use. * * @return */ private String getLanguageInRequestParam() { String language = Util.normalizeLanguage(getContext().getRequest().getParameter("language")); if ((language != null) && (!language.equals(""))) { Object cookieAddedBefore = getExecContext().getProperty(ADD_LANGUAGE_COOKIE_DONE); if ((cookieAddedBefore == null) || !(Boolean) cookieAddedBefore) { if (isInvalidLanguageOrDefault(language)) { // forgetting language cookie Cookie cookie = new Cookie("language", ""); cookie.setMaxAge(0); cookie.setPath("/"); getContext().getResponse().addCookie(cookie); language = webUtilsService.getDefaultLanguage(); } else { // setting language cookie Cookie cookie = new Cookie("language", language); cookie.setMaxAge(60 * 60 * 24 * 365 * 10); cookie.setPath("/"); getContext().getResponse().addCookie(cookie); } getExecContext().setProperty(ADD_LANGUAGE_COOKIE_DONE, new Boolean(true)); } } return language; } boolean isInvalidLanguageOrDefault(String language) { return language.equals("default") || (isSuppressInvalid() && !webUtilsService.getAllowedLanguages().contains(language)); } private boolean isSuppressInvalid() { return getContext().getWiki().getXWikiPreference(CEL_SUPPRESS_INVALID_LANG, CFG_LANGUAGE_SUPPRESS_INVALID, "0", getContext()).equals("1"); } /** * Construct a list of language codes (ISO 639-1) from the Accept-Languages header. This * method filters out some bugs in different browsers or containers, like returning '*' * as a language (Jetty) or using '_' as a language--country delimiter (some versions of * Opera). * * @param request * The client request. * @return A list of language codes, in the client preference order; might be empty if * the header is not well formed. */ @SuppressWarnings("unchecked") private List<String> getAcceptedLanguages(XWikiRequest request) { List<String> result = new ArrayList<String>(); Enumeration<Locale> e = request.getLocales(); while (e.hasMoreElements()) { String language = e.nextElement().getLanguage().toLowerCase(); _LOGGER.debug("getAcceptedLanguages: found language " + language); // All language codes should have 2 letters. if (StringUtils.isAlpha(language)) { result.add(language); } } return result; } void fixTdocForInvalidLanguage(VelocityContext vcontext) { // FIXME should be executed only once per vcontext right? XWikiDocument doc = getContext().getDoc(); if ((doc != null) && (vcontext != null)) { Document vTdocBefore = (Document) vcontext.get("tdoc"); if (isTdocLanguageWrong(vTdocBefore)) { try { XWikiDocument tdoc = doc.getTranslatedDocument(getContext()); try { String rev = (String) getContext().get("rev"); if (StringUtils.isNotEmpty(rev)) { tdoc = getContext().getWiki().getDocument(tdoc, rev, getContext()); } } catch (Exception ex) { _LOGGER.debug("Invalid version, just use the most recent one.", ex); } getContext().put("tdoc", tdoc); vcontext.put("tdoc", tdoc.newDocument(getContext())); } catch (XWikiException exp) { _LOGGER.error("Faild to get translated document for [" + getContext().getDoc().getDocumentReference() + "].", exp); } } else { _LOGGER.debug("skip fixTdocForInvalidLanguage because vTdoc launguage is" + " correct."); } } else { _LOGGER.debug("skip fixTdocForInvalidLanguage doc [" + doc + "] vcontext [" + vcontext + "]."); } } boolean isTdocLanguageWrong(Document vTdocBefore) { if (vTdocBefore == null) { return true; } String vTdocLang = vTdocBefore.getLanguage(); if ("".equals(vTdocLang)) { vTdocLang = vTdocBefore.getDefaultLanguage(); } return (!getContext().getLanguage().equals(vTdocLang)); } }