/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you 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.apache.empire.jsf2.utils; | |
import java.io.Serializable; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.text.SimpleDateFormat; | |
import java.util.Hashtable; | |
import java.util.Locale; | |
import org.apache.empire.commons.DateUtils; | |
import org.apache.empire.commons.StringUtils; | |
import org.apache.empire.db.DBRowSet; | |
import org.apache.empire.exceptions.InternalException; | |
import org.apache.empire.exceptions.InvalidArgumentException; | |
import org.apache.empire.exceptions.UnexpectedReturnValueException; | |
import org.apache.empire.jsf2.pages.PageDefinition; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
/** | |
* This class manages request parameters in a way that they cannot be analyzed and modified by the user | |
* @author doebele | |
* | |
*/ | |
public class ParameterMap implements Serializable | |
{ | |
private static final long serialVersionUID = 1L; | |
private static final Logger log = LoggerFactory.getLogger(ParameterMap.class); | |
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss", Locale.GERMAN); | |
static private MessageDigest md5 = null; | |
{ | |
try | |
{ | |
ParameterMap.md5 = MessageDigest.getInstance("MD5"); | |
} | |
catch (NoSuchAlgorithmException e) | |
{ | |
ParameterMap.log.error("MessageDigest NoSuchAlgorithmException.", e); | |
throw new InternalException(e); | |
} | |
} | |
private final byte[] salt; | |
protected Hashtable<String, String> codeMap = new Hashtable<String, String>(); | |
protected final Hashtable<String, Hashtable<String, Object>> typeMap = new Hashtable<String, Hashtable<String, Object>>(); | |
public ParameterMap() | |
{ | |
String dateTime = dateFormat.format(DateUtils.getTimeNow()); | |
salt = dateTime.getBytes(); | |
} | |
public synchronized String encodeString(String valueAsString) | |
{ | |
if (valueAsString==null) | |
throw new InvalidArgumentException("valueAsString", valueAsString); | |
// log | |
if (log.isTraceEnabled()) | |
log.trace("Generating code for value {}.", valueAsString); | |
// generate code | |
md5.reset(); | |
if (salt!=null) | |
md5.update(salt); | |
md5.update(valueAsString.getBytes()); | |
byte s[] = ParameterMap.md5.digest(); | |
StringBuilder hash = new StringBuilder(32); | |
for (int i = 0; i < s.length; i++) | |
{ // add the hash part | |
// String check = Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);; | |
String part = Integer.toHexString(0x000000ff & s[i]); | |
switch(part.length()) | |
{ | |
case 1: hash.append('0'); | |
case 2: hash.append(part); | |
break; | |
default: | |
throw new UnexpectedReturnValueException(part, "Integer.toHexString"); | |
// hash.append(part.substring(2)); | |
} | |
} | |
return hash.toString(); | |
} | |
public String encodeStringWithCache(String valueAsString) | |
{ | |
String code = codeMap.get(valueAsString); | |
if (code==null) | |
{ // generate code | |
code = encodeString(valueAsString); | |
codeMap.put(valueAsString, code); | |
} | |
return code; | |
} | |
/** | |
* gets a unique name for a given rowset | |
* @param rowset | |
* @return a unique name for the given rowset | |
*/ | |
protected String getRowSetTypeName(DBRowSet rowset) | |
{ | |
/* | |
* alternatively use: | |
* rowset.getName(); | |
* or | |
* rowset.getFullName(); | |
*/ | |
return rowset.getClass().getName(); | |
} | |
/** | |
* puts an object into the parameter map | |
* @param typeName | |
* @param id | |
* @param value | |
*/ | |
protected void putValue(String typeName, String encodedId, Object item) | |
{ // put in Table | |
if (encodedId==null) | |
{ | |
throw new InvalidArgumentException("encodedId", encodedId); | |
} | |
Hashtable<String, Object> map = typeMap.get(typeName); | |
if (map==null) | |
{ map = new Hashtable<String, Object>(1); | |
typeMap.put(typeName, map); | |
} | |
map.put(encodedId, item); | |
} | |
/** | |
* encodes the objectKey and stores the item in the parameter map | |
* @param typeName | |
* @param id | |
* @param value | |
*/ | |
protected String encodeAndStore(String typeName, String objectKey, Object item, boolean useCache) | |
{ // Generate the id | |
String encodedId = (useCache ? encodeStringWithCache(objectKey) : encodeString(objectKey)); | |
// store | |
putValue(typeName, encodedId, item); | |
// return id | |
return encodedId; | |
} | |
public String put(String type, String key, boolean useCache) | |
{ | |
// Generate id and put in map | |
return encodeAndStore(type, key, key, useCache); | |
} | |
/** | |
* Puts an object into the paramter map that implements the ParameterObject interface | |
* @param paramObject | |
* @return | |
*/ | |
public String put(ParameterObject paramObject) | |
{ | |
String objectKey; | |
// check param | |
if (paramObject==null || StringUtils.isEmpty((objectKey=paramObject.getObjectKey()))) | |
throw new InvalidArgumentException("paramObject", paramObject); | |
// Generate id and put in map | |
String type = paramObject.getClass().getName(); | |
return encodeAndStore(type, objectKey, paramObject, false); | |
} | |
public String put(DBRowSet rowset, Object[] key) | |
{ | |
// Generate id and put in map | |
String rowKey = StringUtils.valueOf(key); | |
String type = getRowSetTypeName(rowset); | |
return encodeAndStore(type, rowKey, key, false); | |
} | |
/* | |
* do we really need this? | |
* | |
public String put(Class<? extends Object> c, Object[] key) | |
{ | |
// Generate id and put in map | |
String ref = StringUtils.valueOf(key); | |
String type = c.getName(); | |
return encodeAndStore(type, ref, key, false); | |
} | |
*/ | |
/** | |
* Generates an idParam which is only valid for the given page. | |
* @param targetPage | |
* @param rowset | |
* @param key | |
* @return | |
*/ | |
public String put(PageDefinition targetPage, DBRowSet rowset, Object[] key) { | |
// Generate id and put in map | |
String ref = StringUtils.valueOf(key); | |
String type = targetPage.getPageBeanName() + "$" + getRowSetTypeName(rowset); | |
return encodeAndStore(type, ref, key, false); | |
} | |
/** | |
* Gets an object from the parameter map for a given type and id | |
* @param type the object type (typically the class name) | |
* @param id the encoded idParam | |
* @return the object | |
*/ | |
public Object get(String type, String id) | |
{ | |
Hashtable<String, Object> map = typeMap.get(type); | |
return (map!=null ? map.get(id) : null); | |
} | |
public void clear(String type) | |
{ | |
Hashtable<String, Object> map = typeMap.get(type); | |
if (map!=null) | |
map.clear(); | |
} | |
/** | |
* Puts an object into the paramter map that implements the ParameterObject interface | |
* @param paramType | |
* @param id | |
* @return | |
*/ | |
@SuppressWarnings("unchecked") | |
public <T extends ParameterObject> T get(Class<T> paramType, String id) | |
{ | |
String type = paramType.getName(); | |
Hashtable<String, Object> map = typeMap.get(type); | |
return (T)(map!=null ? map.get(id) : null); | |
} | |
public void clear(Class<? extends ParameterObject> paramType) | |
{ | |
String type = paramType.getName(); | |
clear(type); | |
} | |
/* | |
* do we really need this? | |
* | |
public Object[] getKey(Class<? extends Object> c, String id) | |
{ | |
String type = c.getName(); | |
Hashtable<String, Object> map = typeMap.get(type); | |
return (map!=null ? ((Object[])map.get(id)) : null); | |
} | |
*/ | |
public Object[] getKey(DBRowSet rowset, String id) | |
{ | |
String type = getRowSetTypeName(rowset); | |
Hashtable<String, Object> map = typeMap.get(type); | |
return (map!=null ? ((Object[])map.get(id)) : null); | |
} | |
public void clear(DBRowSet rowset) | |
{ | |
String type = getRowSetTypeName(rowset); | |
clear(type); | |
} | |
/** | |
* returns an record key for a given page | |
* @param page | |
* @param rowset | |
* @param id | |
* @return | |
*/ | |
public Object[] getKey(PageDefinition page, DBRowSet rowset, String id) | |
{ | |
String type = page.getPageBeanName() + "$" + getRowSetTypeName(rowset); | |
Hashtable<String, Object> map = typeMap.get(type); | |
return (map!=null ? ((Object[])map.get(id)) : null); | |
} | |
} |