/** * * Copyright 2014 The Darks ORM Project (Liu lihua) * * 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 darks.orm.core.data.xml; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import darks.orm.app.QueryEnumType; import darks.orm.util.StringHelper.ParamFlag; public class DMLQueryData implements Cloneable { private ConcurrentMap<String, String> sqlMap = new ConcurrentHashMap<String, String>(); private ConcurrentMap<Integer, String> sqlConstituteMap = new ConcurrentHashMap<Integer, String>(); private static final String DEFAULT_KEY = "0000"; private static final int INIT_BUFFER_SIZE = 256; private static final int INIT_HASH_VALUE = 2; private static final int HASH_VALUE_PARAM = 32; public enum DMLQueryDataType { Simple, Select, Constitute }; private String resultType; private Class<?> resultClass; private boolean autoCascade; private String alias; private String attribute; private QueryEnumType queryType; private DMLQueryDataType queryDataType; private AspectData aspectData; private ParamFlag valuesParam; private ParamFlag pageParam; private ParamFlag pageSizeParam; public DMLQueryData() { } public DMLQueryData(String resultType, boolean autoCascade, String alias, String attribute, QueryEnumType queryType, DMLQueryDataType queryDataType) { this.resultType = resultType; this.autoCascade = autoCascade; this.alias = alias; this.attribute = attribute; this.queryType = queryType; this.queryDataType = queryDataType; } public void setSQL(String sql) { sqlMap.put(DEFAULT_KEY, sql); } public void addSQL(String key, String sql) { sqlMap.put(key, sql); } public String getSql() { return getSql(DEFAULT_KEY); } public String getSql(String key) { if (key == null) return null; if (key.indexOf("@") < 0) { key = key.replace(",", "@"); } if (sqlMap.containsKey(key)) { return sqlMap.get(key); } return null; } public String getSql(Object[] values) { String key = null; if (queryDataType == DMLQueryDataType.Simple || values == null) { key = DEFAULT_KEY; return getSql(key); } else if (queryDataType == DMLQueryDataType.Constitute) { return getConstituteSql(values); } else if (queryDataType == DMLQueryDataType.Select) { return getSelectSql(values); } return getSql(key); } public String getConstituteSql(Object[] values) { int key = hash(values); String sql = sqlConstituteMap.get(key); if (sql != null) { return sql; } sql = getSql(DEFAULT_KEY); StringBuffer buf = new StringBuffer(INIT_BUFFER_SIZE); buf.append(sql); for (Object val : values) { if (val == null) continue; sql = getSql(String.valueOf(val)); if (sql == null) continue; if (!sql.startsWith(" ")) buf.append(" "); buf.append(sql); } sql = buf.toString(); sqlConstituteMap.put(key, sql); return sql; } public String getSelectSql(Object[] values) { String key = null; StringBuffer buf = new StringBuffer(); if (values != null) { for (Object val : values) { buf.append(val); buf.append("@"); } } if (buf.length() > 0) buf.deleteCharAt(buf.length() - 1); key = buf.toString(); return getSql(key); } private int hash(Object[] values) { int result = INIT_HASH_VALUE; return getObjectsHashCode(result, values); } private int getObjectHashCode(Object obj, int ret) { int result = HASH_VALUE_PARAM * ret; if (obj == null) return result; if (obj instanceof Boolean) { boolean bln = (Boolean)obj; result = result + (bln ? 0 : 1); } else if (obj instanceof Byte || obj instanceof Character || obj instanceof Short || obj instanceof Integer) { result = result + (Integer)obj; } else if (obj instanceof Long) { long along = (Long)obj; result = result + (int)(along ^ (along >>> 32)); ; } else if (obj instanceof Float) { float afloat = (Float)obj; result = result + Float.floatToIntBits(afloat); } else if (obj instanceof Double) { double adouble = (Double)obj; long tolong = Double.doubleToLongBits(adouble); result = result + (int)(tolong ^ (tolong >>> 32)); } else { result = result + obj.hashCode(); } return result; } private int getObjectsHashCode(int result, Object[] objs) { if (objs == null) return HASH_VALUE_PARAM * result; for (int i = 0; i < objs.length; i++) { result = getObjectHashCode(objs[i], result); } return result; } public ConcurrentMap<String, String> getSqls() { return sqlMap; } public ConcurrentMap<String, String> getSqlMap() { return sqlMap; } public void setSqlMap(ConcurrentMap<String, String> sqlMap) { this.sqlMap = sqlMap; } public String getResultType() { return resultType; } public void setResultType(String resultType) { this.resultType = resultType; } public boolean isAutoCascade() { return autoCascade; } public void setAutoCascade(boolean autoCascade) { this.autoCascade = autoCascade; } public String getAlias() { return alias; } public void setAlias(String alias) { this.alias = alias; } public String getAttribute() { return attribute; } public void setAttribute(String attribute) { this.attribute = attribute; } public QueryEnumType getQueryType() { return queryType; } public void setQueryType(QueryEnumType queryType) { this.queryType = queryType; } public DMLQueryDataType getQueryDataType() { return queryDataType; } public void setQueryDataType(DMLQueryDataType queryDataType) { this.queryDataType = queryDataType; } public Class<?> getResultClass() { return resultClass; } public void setResultClass(Class<?> resultClass) { this.resultClass = resultClass; } public AspectData getAspectData() { return aspectData; } public void setAspectData(AspectData aspectData) { this.aspectData = aspectData; } public ParamFlag getValuesParam() { return valuesParam; } public void setValuesParam(ParamFlag valuesParam) { this.valuesParam = valuesParam; } public ParamFlag getPageParam() { return pageParam; } public void setPageParam(ParamFlag pageParam) { this.pageParam = pageParam; } public ParamFlag getPageSizeParam() { return pageSizeParam; } public void setPageSizeParam(ParamFlag pageSizeParam) { this.pageSizeParam = pageSizeParam; } public DMLQueryData clone() { try { return (DMLQueryData)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return null; } }