/* * Copyright 2012 The Solmix Project * * 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 may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.api.datasource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.application.Application; import org.solmix.api.event.IValidationEvent; import org.solmix.api.jaxb.Eoperation; import org.solmix.api.jaxb.request.Roperation; import org.solmix.commons.util.DataUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * Context for DataSource request. * * @author solmix.f@gmail.com * @since 0.0.1 * @version 110035 2010-12-19 solmix-api */ @SuppressWarnings("unchecked") public class DSRequestData implements java.io.Serializable { private static final Logger log =LoggerFactory.getLogger(DSRequestData.class.getName()); private boolean _allowMultiUpdate; private Object constraints; private List<String> outputs; private boolean forceInvalidateCache; protected String userId; // 验证失败返回的信息 protected String securityFailureMessage; private List<Object> uploadedFiles; private String validationMode; private Roperation Roperation; private String appID; private Boolean isClientRequest; protected Object beforeValidatedValues; public void init() { if (getAppID() == null) setAppID(Application.BUILT_IN_APPLICATION); if (getRepo() == null) repo = "default"; } /** * @return the beforeValidatedValues */ public Object getBeforeValidatedValues() { return beforeValidatedValues; } /** * @param beforeValidatedValues the beforeValidatedValues to set */ public void setBeforeValidatedValues(Object beforeValidatedValues) { this.beforeValidatedValues = beforeValidatedValues; } /** * @return the appId */ public String getAppID() { if (appID == null && this.Roperation != null && Roperation.getAppID() != null) appID = Roperation.getAppID(); return appID; } /** * @param appId the appId to set */ public void setAppID(String appID) { this.appID = appID; } /** * @return the Roperation */ public Roperation getRoperation() { return Roperation; } /** * @param Roperation the Roperation to set */ public void setRoperation(Roperation Roperation) { this.Roperation = Roperation; } public Object getFieldValue(Object fieldName) { Map valueSet = getValues(); if (valueSet != null && valueSet.get(fieldName) != null) return valueSet.get(fieldName); Map criteria = getCriteria(); if (criteria != null && criteria.get(fieldName) != null) return criteria.get(fieldName); else return null; } /** * @return the isExport */ public boolean getIsExport() { if (Roperation == null) return false; return Roperation.isExportResults(); } private Object rawCriteria; private Object rawValues; private Object rawOldValues; /** * {@link org.solmix.api.datasource.DSRequestData#criteria criteria} maybe <code>Map</code> or List < Map > * * @return the criteria */ public Object getRawCriteria() { return rawCriteria; } /** * Add a criteria to DataSourceRequest.<br> * if previous value is a <code>Map</code> Object,just use <code>put(key,value)</code>.if not,use a * <code>List</code> to wrapped. * * @param key * @param value */ public void addToCriteria(String key, Object value) { if (getRawCriteria() == null) { rawCriteria = new HashMap<String, Object>(); ((Map<Object,Object>) rawCriteria).put(key, value); } else { if (rawCriteria instanceof Map) { ((Map<Object,Object>) rawCriteria).put(key, value); } else { rawCriteria = DataUtils.makeListIfSingle(rawCriteria); Map<Object,Object> _tmp = new HashMap<Object,Object>(); _tmp.put(key, value); ((List<Object>) rawCriteria).add(_tmp); } } } public void addToUploadedFiles(Object fileItem) { if (getUploadedFiles() == null) uploadedFiles = new ArrayList<Object>(); uploadedFiles.add(fileItem); } /** * @param criteria the criteria to set */ public void setCriteria(Object criteria) { this.rawCriteria = criteria; } /** * @return the values */ public Object getRawValues() { return rawValues; } /** * The values always be Map or List of Map. * * @param values */ public void setValues(Object values) { this.rawValues = values; } private Eoperation operationType; String downloadFieldName; String downloadFileName; private Object rawSortBy; public static final long FETCH_ALL = -1L; private Integer batchSize; public static final long ENDROW_UNSET = -1L; private String repo; private List<IValidationEvent> validationList; Map<String, Object> templateContext; private Object operation; private Integer endRow; private Integer startRow; private Integer totalRow; /** * Return this request Operation ID.This used for indicate unique of operation. * * @return the operation */ public Object getOperation() { if (operation == null && getRoperation() != null) { operation = getRoperation().getOperationId(); } return operation; } /** * Return this request Operation ID.This used for indicate unique of operation. * * @return the operation */ public String getOperationId() { if (operation == null && getRoperation() != null) operation = getRoperation().getOperationId(); if (operation != null) { if (operation instanceof String) return operation.toString(); else if (operation instanceof Map<?, ?>) { Map<String, String> tmp = (Map<String, String>) operation; return tmp.get("dataSource") + "_" + tmp.get("type"); } else if( operation instanceof Element){ Element e =(Element)operation; Node textV= e.getFirstChild(); if(textV instanceof Text) return ((Text)textV).getData(); }else { if (log.isWarnEnabled()) log.warn("operation is validte object:" + operation.toString()); } } return null; } /** * @param operation the operation to set */ public void setOperation(String operation) { this.operation = operation; } public void addToTemplateContext(String name, Object value) { if (templateContext == null) templateContext = new HashMap<String, Object>(); templateContext.put(name, value); } public void addValidationEvent(IValidationEvent event) { if (validationList == null) validationList = new ArrayList<IValidationEvent>(); validationList.add(event); } /** * Indicate this is a request from client,not from internal,for usually,the request along with a * {@link org.solmix.ds.context.Context} * * @return the isClientRequest */ public Boolean getIsClientRequest() { return isClientRequest; } /** * Indicate this is a request from client,not from internal,for usually,the request along with a * {@link org.solmix.ds.context.Context} * * @param isClientRequest the isClientRequest to set */ public void setIsClientRequest(Boolean isClientRequest) { this.isClientRequest = isClientRequest; } /** * @return the isDownload */ public Boolean getIsDownload() { if (getDownloadFieldName() != null) { Eoperation opType = getOperationType(); if (opType == Eoperation.DOWNLOAD_FILE || opType == Eoperation.VIEW_FILE) return true; } return false; } /** * @return the operationType */ public Eoperation getOperationType() { if (operationType == null && getOperation() != null) { if (getRoperation().getOperationType() != null) operationType = Eoperation.fromValue(getRoperation().getOperationType()); if (operationType == null) { String operation = this.getOperationId(); if (operation != null && operation.indexOf("_") != -1) operationType = Eoperation.fromValue(operation.substring(operation.lastIndexOf("_"))); } } return operationType; } /** * @param operationType the operationType to set */ public void setOperationType(Eoperation operationType) { this.operationType = operationType; } /** * @return the downloadFieldName */ public String getDownloadFieldName() { return downloadFieldName; } /** * @param downloadFieldName the downloadFieldName to set */ public void setDownloadFieldName(String downloadFieldName) { this.downloadFieldName = downloadFieldName; } /** * @return the downloadFileName */ public String getDownloadFileName() { return downloadFileName; } /** * @param downloadFileName the downloadFileName to set */ public void setDownloadFileName(String downloadFileName) { this.downloadFileName = downloadFileName; } /** * @return the sortBy */ public Object getRawSortBy() { return rawSortBy; } /** * @param sortBy the sortBy to set */ public void setRawSortBy(Object sortBy) { this.rawSortBy = sortBy; } /** * @return the batchSize */ public Integer getBatchSize() { if (batchSize == null) batchSize = getEndRow() - getStartRow() > 0 ? getEndRow() - getStartRow() : 0; return batchSize; } /** * @param batchSize the batchSize to set */ public void setBatchSize(Integer batchSize) { this.batchSize = batchSize; } /** * Cache the validationEvent for current datasource request instance. * * @return the validationList */ public List<IValidationEvent> getValidationList() { return validationList; } /** * @param validationList the validationList to set */ public void setValidationList(List<IValidationEvent> validationList) { this.validationList = validationList; } /** * no set method,because this method just for convenience. * * @return the dataSourceName */ public Object getDataSourceNames() { if (Roperation != null) { return Roperation.getDataSource(); } return null; } /** * @return the repo */ public String getRepo() { return repo; } /** * @param repo the repo to set */ public void setRepo(String repo) { this.repo = repo; } /** * @return the templateContext */ public Map<String, Object> getTemplateContext() { return templateContext; } /** * @param templateContext the templateContext to set */ public void setTemplateContext(Map<String, Object> templateContext) { this.templateContext = templateContext; } /** * Indicate allow multiple update. * * @return the _allowMultiUpdate */ public boolean is_allowMultiUpdate() { return _allowMultiUpdate; } /** * @param allowMultiUpdate the _allowMultiUpdate to set */ public void set_allowMultiUpdate(boolean allowMultiUpdate) { _allowMultiUpdate = allowMultiUpdate; } /** * Alway List * * @return the constraints */ public Object getConstraints() { return constraints; } public void addToConstraints(Object obj) { if (obj == null) return; if (constraints == null) constraints = new ArrayList<Object>(); List newConstraints = DataUtils.makeListIfSingle(obj); if (newConstraints.contains("*")) { constraints = null; return; } else { DataUtils.addDisjunctionToSet((List) constraints, newConstraints); return; } } /** * @param constraints the constraints to set */ public void setConstraints(Object constraints) { this.constraints = constraints; } /** * @return the outputs */ public List<String> getOutputs() { return outputs; } public void addOutputs(Object obj) { if (obj == null) return; if (outputs == null) outputs = new ArrayList<String>(); List<Object> addedOutputs = DataUtils.makeListIfSingle(obj); if (addedOutputs.contains("*")) { outputs = null; return; } else { DataUtils.addDisjunctionToSet(outputs, addedOutputs); return; } } /** * @param outputs the outputs to set */ public void setOutputs(List<String> outputs) { this.outputs = outputs; } /** * @return the forceInvalidateCache */ public boolean isForceInvalidateCache() { return forceInvalidateCache; } /** * @param forceInvalidateCache the forceInvalidateCache to set */ public void setForceInvalidateCache(boolean forceInvalidateCache) { this.forceInvalidateCache = forceInvalidateCache; } /** * @return the userId */ public String getUserId() { return userId; } /** * @param userId the userId to set */ public void setUserId(String userId) { this.userId = userId; } /** * @return the securityFailureMessage */ public String getSecurityFailureMessage() { return securityFailureMessage; } /** * @param securityFailureMessage the securityFailureMessage to set */ public void setSecurityFailureMessage(String securityFailureMessage) { this.securityFailureMessage = securityFailureMessage; } /** * @return the fetchAll */ public static long getFetchAll() { return FETCH_ALL; } /** * @return the endrowUnset */ public static long getEndrowUnset() { return ENDROW_UNSET; } /** * */ private static final long serialVersionUID = -8718372768588837582L; /** * @return */ public List<Object> getUploadedFiles() { return uploadedFiles; } /** * @param uploadedFiles the uploadedFiles to set */ public void setUploadedFiles(List<Object> uploadedFiles) { this.uploadedFiles = uploadedFiles; } public String getValidationMode() { return validationMode; } /** * <code> old values</code> must be one of List<Map> with size 1,or Map. * * @return */ public Object getRawOldValues() { return rawOldValues; } /** * <code> old values</code> must be one of List<Map> with size 1,or Map. * * @param oldValues */ public void setRawOldValues(Object oldValues) { this.rawOldValues = oldValues; } /** * Convenience for get {@link org.solmix.api.datasource.DSRequestData#getRawOldValues()}.get <code>rawOldValues</code> as * a <code>Map</code> * * @return */ public Map getOldValues() { Object values = getRawOldValues(); if (values instanceof List<?>) { List<?> l = (List<?>) values; if (l.size() == 0) return null; if (l.size() == 1) { return (Map) l.get(0); } else { log.warn("getOldValues() called on dsRequest containing multiple sets of values, returning first in list."); return (Map) l.get(0); } } else { return (Map) values; } } /** * Convenience for get {@link org.solmix.api.datasource.DSRequestData#getRawOldValues()}.get <code>rawOldValues</code> as * a <code>List</code> * * @return */ public List getOldValueSets() { return DataUtils.makeListIfSingle(getRawOldValues()); } /** * get {@link org.solmix.api.datasource.DSRequestData#getRawCriteria()} as a <code>Map</code> * <p> * if {@link org.solmix.api.datasource.DSRequestData#getOperationType() OperationType} is * {@link org.solmix.api.jaxb.Eoperation.ADD ADD} the criteria is from * {@link org.solmix.api.datasource.DSRequestData#getValues()} if the OperationType is * {@link org.solmix.api.jaxb.Eoperation.UPDATE UPDATE} and {@link #getRawCriteria()} is null ,return * {@link #getValues()} * * @return */ public Map<String, Object> getCriteria() { if (getOperationType() == Eoperation.ADD) { return getValues(); } Object criteria = getRawCriteria(); if (getOperationType() == Eoperation.UPDATE && criteria == null) { criteria = getRawValues(); } if (criteria instanceof List) { List<Object> l = (List<Object>) criteria; if (l.size() == 0) return null; if (l.size() == 1) { return (Map<String, Object>) l.get(0); } else { log.warn("getCriteria() called on dsRequest containing multiple where clauses, returning first in list."); return (Map<String, Object>) l.get(0); } } else if(criteria instanceof Map<?, ?>){ return (Map<String, Object>) criteria; }else{ try { return DataUtils.getProperties(criteria, true); } catch (Exception e) { } return null; } } /** * get {@link org.solmix.api.datasource.DSRequestData#getRawCriteria()} as a <code>List</code> * * @return */ public List<?> getCriteriaSets() { if (getOperationType().equals(Eoperation.ADD)) { return getValueSets(); } return DataUtils.makeListIfSingle(getRawCriteria()); } /** * get {@link org.solmix.api.datasource.DSRequestData#getValues()} as a <code>Map</code> * <p> * If {@link org.solmix.api.datasource.DSRequestData#getOperationType() OperationType} is * {@link org.solmix.api.jaxb.Eoperation.FETCH FETCH} or {@link org.solmix.api.jaxb.Eoperation.REMOVE REMOVE} return * {@link org.solmix.api.datasource.DSRequestData#getCriteria()} else return * {@link org.solmix.api.datasource.DSRequestData#getRawValues() RawValues} * * @return */ public Map<String, Object> getValues() { if (getOperationType() == Eoperation.FETCH || getOperationType() == Eoperation.REMOVE) return getCriteria(); Object values = getRawValues(); if (values instanceof List<?>) { List<?> l = (List<?>) values; if (l.size() == 0) return null; if (l.get(0) instanceof Map<?,?>) { if (l.size() == 1) { return (Map<String, Object>) l.get(0); } else { log.warn("getValues() called on dsRequest containing multiple sets of values, returning first in list."); return (Map<String, Object>) l.get(0); } } else { log.debug("getValues() called on dsRequest,and the values is not the List of map.ignore this value."); return null; } } else if (values instanceof Map<?, ?>) { return (Map<String, Object>) values; } else { return null; } } /** * get {@link org.solmix.api.datasource.DSRequestData#getValues()} as a <code>List</code> * * @return */ public List<?> getValueSets() { if (getOperationType() == Eoperation.FETCH || getOperationType() == Eoperation.REMOVE) { return getCriteriaSets(); } else { return DataUtils.makeListIfSingle(getRawValues()); } } /** * Return sort field ,if there is a list for sort return the first one. * * @return */ public String getSortBy() { if (rawSortBy instanceof List) { List<?> l = (List<?>) rawSortBy; if (l.size() == 0) return null; if (l.size() == 1) { return (String) l.get(0); } else { log.warn("getSortBy() called on dsRequest containing multiple sortBy fields, returning first in list."); return (String) l.get(0); } } else { return (String) rawSortBy; } } public List<?> getSortByFields() { return DataUtils.makeListIfSingle(rawSortBy); } /** * @return */ public boolean isPaged() { if (getStartRow() != null && getStartRow() >= 0 && getEndRow() != null && getEndRow() > 0 && getBatchSize() != null && getBatchSize() > 0) return true; return false; } public Integer getEndRow() { if (endRow == null) endRow = Roperation == null ? null : Roperation.getEndRow(); return endRow; } public void setEndRow(Integer endRow) { this.endRow = endRow; } public Integer getStartRow() { if (startRow == null) startRow = Roperation == null ? null : Roperation.getStartRow(); return startRow; } public void setStartRow(Integer startRow) { this.startRow = startRow; } /** * @return the totalRow */ public Integer getTotalRow() { if(totalRow==null) totalRow = Roperation == null ? null : Roperation.getTotalRow(); return totalRow; } /** * @param totalRow the totalRow to set */ public void setTotalRow(Integer totalRow) { this.totalRow = totalRow; } }