/** * Copyright 2013, WebGate Consulting AG * * Licensed 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.openntf.xpt.oneui.component; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.el.MethodBinding; import javax.servlet.http.HttpServletResponse; import lotus.domino.Document; import lotus.domino.Name; import lotus.domino.NotesException; import org.openntf.xpt.core.json.JSONService; import org.openntf.xpt.core.utils.ErrorJSONBuilder; import org.openntf.xpt.core.utils.ValueBindingSupport; import org.openntf.xpt.core.utils.logging.LoggerFactory; import org.openntf.xpt.oneui.kernel.INamePickerValueService; import org.openntf.xpt.oneui.kernel.JsonResult; import org.openntf.xpt.oneui.kernel.NameEntry; import org.openntf.xpt.oneui.kernel.NamePickerProcessor; import com.ibm.commons.util.StringUtil; import com.ibm.domino.services.util.JsonWriter; import com.ibm.xsp.FacesExceptionEx; import com.ibm.xsp.binding.MethodBindingEx; import com.ibm.xsp.component.FacesAjaxComponent; import com.ibm.xsp.component.UIInputEx; import com.ibm.xsp.extlib.util.ExtLibUtil; import com.ibm.xsp.model.domino.wrapped.DominoDocument; import com.ibm.xsp.util.ManagedBeanUtil; import com.ibm.xsp.util.StateHolderUtil; import com.ibm.xsp.util.TypedUtil; import com.ibm.xsp.webapp.XspHttpServletResponse; public class UINamePicker extends UIInputEx implements FacesAjaxComponent { public static final String COMPONENT_TYPE = "org.openntf.xpt.oneui.component.uinamepicker"; //$NON-NLS-1$ public static final String COMPONENT_FAMILY = "org.openntf.xpt.oneui.component.uinamepicker"; //$NON-NLS-1$ public static final String RENDERER_TYPE = "org.openntf.xpt.oneui.component.uinamepicker"; //$NON-NLS-1$ private static final String[] VAR_METHOD = { "docName" }; private String m_Database; private String m_View; private String m_LookupView; private String m_SearchQuery; private String m_RefreshId; private boolean m_DisplayLabel; private MethodBinding m_BuildLabel; private MethodBinding m_BuildValue; private MethodBinding m_BuildLine; private Boolean m_ReadOnly; private String m_NameValueBean; public UINamePicker() { setRendererType(RENDERER_TYPE); } @Override public String getFamily() { return COMPONENT_FAMILY; } public String getDatabase() { return ValueBindingSupport.getValue(m_Database, "database", this, null, getFacesContext()); } public void setDatabase(String database) { m_Database = database; } public String getView() { return ValueBindingSupport.getValue(m_View, "view", this, null, getFacesContext()); } public void setView(String view) { m_View = view; } public String getLookupView() { return m_LookupView; } public void setLookupView(String lookupView) { m_LookupView = lookupView; } public String getSearchQuery() { return ValueBindingSupport.getValue(m_SearchQuery, "searchQuery", this, null, getFacesContext()); } public void setSearchQuery(String searchQuery) { m_SearchQuery = searchQuery; } public String getNameValueBean() { return ValueBindingSupport.getValue(m_NameValueBean, "nameValueBean", this, null, getFacesContext()); } public void setNameValueBean(String nameValueBean) { m_NameValueBean = nameValueBean; } public boolean isDisplayLabel() { return m_DisplayLabel; } public void setDisplayLabel(boolean displayLabel) { m_DisplayLabel = displayLabel; } public String getRefreshId() { return ValueBindingSupport.getValue(m_RefreshId, "refreshId", this, null, getFacesContext()); } public void setRefreshId(String refreshId) { m_RefreshId = refreshId; } public MethodBinding getBuildLabel() { return m_BuildLabel; } public void setBuildLabel(MethodBinding buildLabel) { m_BuildLabel = buildLabel; } public MethodBinding getBuildValue() { return m_BuildValue; } public void setBuildValue(MethodBinding buildValue) { m_BuildValue = buildValue; } public MethodBinding getBuildLine() { return m_BuildLine; } public void setBuildLine(MethodBinding buildLine) { m_BuildLine = buildLine; } public boolean isReadOnly() { return ValueBindingSupport.getValue(m_ReadOnly, "readOnly", this, Boolean.FALSE, FacesContext.getCurrentInstance()); } public void setReadOnly(boolean readOnly) { m_ReadOnly = readOnly; } // This is to maintain the compatibility with JSF // We add this pseudo property as it can be used by the readonly renderkit public boolean isReadonly() { return isReadOnly(); } public void setReadonly(boolean readOnly) { setReadOnly(readOnly); } // SAVE & RESTORE of the Values public void restoreState(FacesContext context, Object state) { Object[] values = (Object[]) state; super.restoreState(context, values[0]); m_Database = (String) values[1]; m_View = (String) values[2]; m_RefreshId = (String) values[3]; m_SearchQuery = (String) values[4]; m_BuildLabel = StateHolderUtil.restoreMethodBinding(context, this, values[5]); m_BuildLine = StateHolderUtil.restoreMethodBinding(context, this, values[6]); m_BuildValue = StateHolderUtil.restoreMethodBinding(context, this, values[7]); m_LookupView = (String) values[8]; m_NameValueBean = (String) values[9]; m_DisplayLabel = (Boolean) values[10]; } @Override public Object saveState(FacesContext context) { Object[] values = new Object[11]; values[0] = super.saveState(context); values[1] = m_Database; values[2] = m_View; values[3] = m_RefreshId; values[4] = m_SearchQuery; values[5] = StateHolderUtil.saveMethodBinding(context, m_BuildLabel); values[6] = StateHolderUtil.saveMethodBinding(context, m_BuildLine); values[7] = StateHolderUtil.saveMethodBinding(context, m_BuildValue); values[8] = m_LookupView; values[9] = m_NameValueBean; values[10] = m_DisplayLabel; return values; } @Override public boolean handles(FacesContext arg0) { return true; } @Override public void processAjaxRequest(FacesContext context) throws IOException { HttpServletResponse httpResponse = (HttpServletResponse) context.getExternalContext().getResponse(); if (httpResponse instanceof XspHttpServletResponse) { XspHttpServletResponse r = (XspHttpServletResponse) httpResponse; r.setCommitted(true); httpResponse = r.getDelegate(); } try { httpResponse.setContentType("text/json"); httpResponse.setCharacterEncoding("utf-8"); JsonWriter jsWriter = new JsonWriter(httpResponse.getWriter(), true); Map<String, String> localMap = TypedUtil.getRequestParameterMap(context.getExternalContext()); String strSearch = localMap.get("$$value"); List<NameEntry> lstEntries = new ArrayList<NameEntry>(); if (strSearch != null) { lstEntries = searcheNameValues(context, strSearch); } JsonResult jsResult = JsonResult.generateOKResult(lstEntries); JSONService.getInstance().process2JSON(jsWriter, jsResult); jsWriter.close(); } catch (Exception e) { ErrorJSONBuilder.getInstance().processError2JSON(httpResponse, 9999, "Error during parsing!", e); } } private List<NameEntry> searcheNameValues(FacesContext context, String strSearch) throws NotesException { List<NameEntry> lstEntries; INamePickerValueService service = getNamePickerValueService(context); lstEntries = service.getTypeAheadValues(this, strSearch); return lstEntries; } public INamePickerValueService getNamePickerValueService(FacesContext context) { String nameValueBeanName = getNameValueBean(); if (nameValueBeanName != null) { Object nvBean = ManagedBeanUtil.getBean(context, getNameValueBean()); if (!(nvBean instanceof INamePickerValueService)) { throw new FacesExceptionEx(null, "Bean {0} is not a INamePickerValueService", nameValueBeanName); } return (INamePickerValueService) nvBean; } else { return NamePickerProcessor.INSTANCE; } } public String getDisplayLableValue(Document docSearch) { String strLabel = ""; try { String strDbPath = docSearch.getParentDatabase().getServer() + "!!" + docSearch.getParentDatabase().getFilePath(); DominoDocument dDoc = DominoDocument.wrap(strDbPath, docSearch, "", "", false, "", ""); Object[] objExec = { dDoc }; strLabel = computeValueMB(m_BuildLabel, objExec); if (strLabel == null) { strLabel = getField(docSearch, "InternetAddress"); } } catch (Exception ex) { LoggerFactory.logError(getClass(), "getDisplayLabelValue", ex); } return strLabel; } public NameEntry getDocumentEntryRepresentation(Document docSearch) { try { String strDbPath = docSearch.getParentDatabase().getServer() + "!!" + docSearch.getParentDatabase().getFilePath(); DominoDocument dDoc = DominoDocument.wrap(strDbPath, docSearch, "", "", false, "", ""); Object[] objExec = { dDoc }; String strLine = computeValueMB(m_BuildLine, objExec); if (strLine == null) { strLine = getField(docSearch, "InternetAddress"); } String strValue = computeValueMB(m_BuildValue, objExec); if (strValue == null) { strValue = getField(docSearch, "FullName"); Name non = docSearch.getParentDatabase().getParent().createName(strValue); strValue = non.getAbbreviated(); non.recycle(); } String strLabel = computeValueMB(m_BuildLabel, objExec); if (strLabel == null) { strLabel = getField(docSearch, "InternetAddress"); } if (StringUtil.isEmpty(strValue)) { return null; } if (StringUtil.isEmpty(strLine)) { if (StringUtil.isEmpty(strLabel)) { strLine = strValue; strLabel = strValue; } else { strLine = strLabel; } } return new NameEntry(strValue, strLabel, strLine); } catch (Exception ex) { LoggerFactory.logError(getClass(), "General Error", ex); } return null; } private String getField(Document docSearch, String strFieldName) { try { return docSearch.getItemValueString(strFieldName); } catch (Exception ex) { LoggerFactory.logError(getClass(), "getField", ex); return ""; } } private String computeValueMB(MethodBinding mb, Object[] objExec) { String strRC = null; if (mb != null) { if (mb instanceof MethodBindingEx) { ((MethodBindingEx) mb).setComponent(this); ((MethodBindingEx) mb).setParamNames(VAR_METHOD); } Object objRC = mb.invoke(getFacesContext(), objExec); strRC = "" + objRC; } return strRC; } public String buildJSFunctionCall(NameEntry nam) { StringBuilder sb = new StringBuilder(buildJSFunctionName()); sb.append("('"); sb.append(nam.getLabel()); sb.append("','"); sb.append(nam.getValue()); sb.append("');"); return sb.toString(); } public String buildJSFunctionName() { String strID = getClientId(getFacesContext()); return "addName_" + ExtLibUtil.encodeJSFunctionName(strID); } public String buildFTSearch(String strSearch) { String strPattern = getSearchQuery(); if (StringUtil.isEmpty(strPattern)) { return null; } return strPattern.replace("###VALUE###", strSearch); } }