package it.softecspa.fileproxy.services; import it.softecspa.fileproxy.services.common.ResponseOutcome; import it.softecspa.fileproxy.services.common.UniversalStatementException; import it.softecspa.fileproxy.services.common.core.request.Protocollo; import it.softecspa.kahuna.lang.XString; import it.softecspa.kahuna.util.HtmlEscape; import it.softecspa.kahuna.util.calendar.EnterpriseCalendar; import it.softecspa.kahuna.util.calendar.EnterpriseCalendarIT; import it.softecspa.kahuna.util.calendar.EnterpriseCalendarUTC; import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Date; import java.util.StringTokenizer; import javax.mail.internet.MimeUtility; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; public class HttpClazzTransformer { private static Logger log = Logger.getLogger(HttpClazzTransformer.class); private final boolean maskError = false; public enum HttpRequestSource { HTTP_HEADER , HTTP_PARAMETER , HTTP_HEADER_PARAMETER ; public String get(HttpServletRequest request, String prefix, String name) { if (equals(HTTP_HEADER)) { // Leggo la variabile dall'HEADER return request.getHeader(prefix+name); } else if (equals(HTTP_PARAMETER)) { // Leggo la variabile dai PARAMETRI return request.getParameter(name); } else if (equals(HTTP_HEADER_PARAMETER)) { // Leggo la variabile sia da HEADER che dai PARAMETRI con precedenza su header String value = request.getHeader(prefix+name); if (value!=null) return value; return request.getParameter(name); } return null; } public String getWithoutUppercase(HttpServletRequest request, String prefix, String name) { name = name.replaceAll("[A-Z]", "-$0").toLowerCase(); if (equals(HTTP_HEADER)) { // Leggo la variabile dall'HEADER return request.getHeader(prefix+name); } else if (equals(HTTP_PARAMETER)) { // Leggo la variabile dai PARAMETRI return request.getParameter(name); } else if (equals(HTTP_HEADER_PARAMETER)) { // Leggo la variabile sia da HEADER che dai PARAMETRI con precedenza su header String value = request.getHeader(prefix+name); if (value!=null) return value; return request.getParameter(name); } return null; } } public enum HeaderEncoding { NONE , HTML_ESCAPE , RFC2047 ; } private HttpRequestSource http_source; private String prefix; private HeaderEncoding responseHeaderEncoding; public HttpClazzTransformer (HttpRequestSource source) { this(source,""); } public HttpClazzTransformer (HttpRequestSource source, String prefix) { this(source, prefix, HeaderEncoding.RFC2047); } public HttpClazzTransformer (HttpRequestSource source, String prefix, HeaderEncoding responseHeaderEncoding) { this.http_source = source; this.prefix = prefix; this.responseHeaderEncoding = responseHeaderEncoding; } /** * @deprecated * @param statement * @param value * @return * @throws UniversalStatementException */ public static Class forName(String statement, String value) throws UniversalStatementException { return forName(HttpClazzTransformer.class, statement, value); } public static Class forName(Class base, String statement, String value) throws UniversalStatementException { String classname = base.getPackage().getName()+"."+value+"."+XString.toUpperCaseFirst(statement)+XString.toUpperCaseFirst(value)+"Type"; // Se trovo un "-" devo mettere a maiuscolo la lettera seguente int pos; while ((pos = classname.indexOf("-"))>=0) { classname = classname.substring(0,pos)+XString.toUpperCaseFirst(classname.substring(pos+1)); } try { if (log.isTraceEnabled()) log.trace("Use class named "+classname); return Class.forName(classname); } catch (ClassNotFoundException e) { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CLASS_NOT_FOUND.getReturnCode() , ResponseOutcome.PS_REQUEST_CLASS_NOT_FOUND.getMessage()+" ["+classname+"]"); } } /** * Crea una istanza di una classe recuperando i valori dalle variabili di HEADER * @param clazz * @param request * @return * @throws UniversalStatementException */ public Object newInstance(Class clazz, HttpServletRequest request, boolean skipNull) throws UniversalStatementException { K result = newInstance(clazz); /* * Ciclo su tutti i metodi per valorizzarli a partire da quello che trovo nel'header */ if (log.isDebugEnabled()) log.debug("<<<< "+http_source.name()+" 2 class conversion for (prefix '"+prefix+"'): "+result.getClass().getName()); Method[] methods = result.getClass().getMethods(); for (Method method : methods) { if (!method.getName().startsWith("set")) continue; Class[] parameterType = method.getParameterTypes(); //if (parameterType.length!=1) continue; Object[] value = new Object[parameterType.length]; String name = XString.toLowerCaseFirst(method.getName().substring(3)); boolean allNull = true; for (int i=0; i>>> Class 2 HEADER conversion for (prefix '"+prefix+"'): "+object.getClass().getName()); Method[] methods = object.getClass().getMethods(); for (Method method : methods) { if (!method.getName().startsWith("get")) continue; if (method.getName().equals("getClass")) continue; if (log.isTraceEnabled()) log.trace(">> method: "+method.getName()); String name = XString.toLowerCaseFirst(method.getName().substring(3)); Class clazz = method.getReturnType(); Object value = null; try { value = method.invoke(object, (Object[])null); } catch (IllegalArgumentException e) { continue; } catch (IllegalAccessException e) { continue; } catch (InvocationTargetException e) { continue; } field2Header(prefix ,name, value, clazz, response); } } private Object castValue2Class(String valueH, Class type) throws UniversalStatementException { if (XString.isBlankNullTrim(valueH)) return null; if (type.equals(String.class)) { return new String(valueH); } else if (type.equals(Integer.class)) { try { return new Integer(valueH.trim()); } catch (NumberFormatException e) { if (maskError) { log.warn("something2field (value2Integer) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(Boolean.class)) { valueH = valueH.trim(); if (valueH.equals("1") || valueH.equalsIgnoreCase("true")) { return Boolean.TRUE; } if (valueH.equals("0") || valueH.equalsIgnoreCase("false")) { return Boolean.FALSE; } return null; } else if (type.equals(Protocollo.class)) { try { return Protocollo.parse(valueH); } catch (Exception e) { if (maskError) { log.warn("something2field (value2Integer) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(EnterpriseCalendar.class)) { try { return new EnterpriseCalendar(valueH.trim(), EnterpriseCalendar.PATTERNS_UTC); } catch (Exception e) { if (maskError) { log.warn("something2field (value2EnterpriseCalendar) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(Long.class)) { try { return new Long(valueH.trim()); } catch (NumberFormatException e) { if (maskError) { log.warn("something2field (value2Long) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(BigDecimal.class)) { try { return new BigDecimal(normalizeCommaPoint(valueH.trim())); } catch (NumberFormatException e) { if (maskError) { log.warn("something2field (value2BigDecimal) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(BigInteger.class)) { try { return new BigInteger(valueH.trim()); } catch (NumberFormatException e) { if (maskError) { log.warn("something2field (value2BigInteger) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(Double.class)) { try { return new Double(normalizeCommaPoint(valueH.trim())); } catch (NumberFormatException e) { if (maskError) { log.warn("something2field (value2Double) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(Float.class)) { try { return new Float(normalizeCommaPoint(valueH.trim())); } catch (NumberFormatException e) { if (maskError) { log.warn("something2field (value2Float) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else if (type.equals(Date.class)) { try { EnterpriseCalendar appo = new EnterpriseCalendar(valueH.trim(), "yyyy-MM-dd"); return new Date(appo.getTimeInMillis()); } catch (Exception e) { if (maskError) { log.warn("something2field (value2Date) :"+e.toString()); return null; } else { throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getReturnCode(), ResponseOutcome.PS_REQUEST_CAST_EXCEPTION.getMessage()); } } } else { log.error("something2field, unsupported type "+type); throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_UNSUPPORTED_TYPE.getReturnCode() , ResponseOutcome.PS_REQUEST_UNSUPPORTED_TYPE.getMessage()+": "+type); } } /** * Normalizzazione . (punto) e , (virgola) * @param value * @return */ private String normalizeCommaPoint(String value) { if (value.indexOf(",")>=0) { return value.replaceAll(",", "."); } return value; } public Object something2field(String name, Class type, HttpServletRequest request) throws UniversalStatementException { String valueH = http_source.get(request, prefix, name); if (XString.isBlankNullTrim(valueH)) { if (name.equals(name.toLowerCase())) return null; valueH = http_source.getWithoutUppercase(request, prefix, name); } if (XString.isBlankNullTrim(valueH)) return null; try { if (type.isArray()) { Class typeI = type.getComponentType(); StringTokenizer values = new StringTokenizer(valueH,","); int count = values.countTokens(); Object ret[] = null; if (typeI.equals(String.class)) { ret = new String[count]; } else if (typeI.equals(Integer.class)) { ret = new Integer[count]; } else if (typeI.equals(Long.class)) { ret = new Long[count]; } else if (typeI.equals(Boolean.class)) { ret = new Boolean[count]; } else if (typeI.equals(BigDecimal.class)) { ret = new BigDecimal[count]; } else if (typeI.equals(BigInteger.class)) { ret = new BigInteger[count]; } else if (typeI.equals(Double.class)) { ret = new Double[count]; } else if (typeI.equals(Float.class)) { ret = new Float[count]; } else if (typeI.equals(EnterpriseCalendar.class)) { ret = new EnterpriseCalendar[count]; } else { log.error("Unsupported type "+type); throw new UniversalStatementException(ResponseOutcome.PS_REQUEST_UNSUPPORTED_ATYPE.getReturnCode() , ResponseOutcome.PS_REQUEST_UNSUPPORTED_ATYPE.getMessage()+": "+typeI); } if (count==0) return ret; for (int i=0;values.hasMoreTokens();) { ret[i++] = castValue2Class(values.nextToken(), typeI); } return ret; } else { return castValue2Class(valueH, type); } } catch (UniversalStatementException e) { throw new UniversalStatementException((e.getMessage()!=null?e.getMessage():e.toString())+" ['"+name+"']", e); } } private void field2Header(String prefix, String name, Object value, Class type, HttpServletResponse response) throws UniversalStatementException { if (value==null) return; name = prefix + name; if (type.equals(String.class)) { setEncodedHeader(response, name, (String)value); } else if (type.equals(Integer.class)) { setEncodedHeader(response, name, ((Integer)value).toString()); } else if (type.equals(Long.class)) { setEncodedHeader(response, name, ((Long)value).toString()); } else if (type.equals(Boolean.class)) { setEncodedHeader(response, name, ((Boolean)value).booleanValue()?"1":"0"); } else if (type.equals(BigDecimal.class)) { setEncodedHeader(response, name, ((BigDecimal)value).toString()); } else if (type.equals(BigInteger.class)) { setEncodedHeader(response, name, ((BigInteger)value).toString()); } else if (type.equals(Double.class)) { setEncodedHeader(response, name, ((Double)value).toString()); } else if (type.equals(Float.class)) { setEncodedHeader(response, name, ((Float)value).toString()); } else if (type.equals(EnterpriseCalendar.class)) { setEncodedHeader(response, name, ((EnterpriseCalendar)value).formatISO8601zulu()); } else if (type.equals(EnterpriseCalendarUTC.class)) { setEncodedHeader(response, name, ((EnterpriseCalendar)value).formatISO8601zulu()); } else if (type.equals(EnterpriseCalendarIT.class)) { setEncodedHeader(response, name, ((EnterpriseCalendar)value).formatISO8601zulu()); } else { log.error("Unsupported type "+type); throw new UniversalStatementException(ResponseOutcome.PS_RESPONSE_UNSUPPORTED_TYPE.getReturnCode() , ResponseOutcome.PS_RESPONSE_UNSUPPORTED_TYPE.getMessage()+": "+type); } } public void setEncodedHeader(HttpServletResponse response, String key, String value) { if (responseHeaderEncoding==HeaderEncoding.RFC2047) { try { response.setHeader(key, MimeUtility.encodeText(value,"UTF-8",null)); } catch (UnsupportedEncodingException e) { log.warn("UnsupportedEncodingException encoding value for key 'key': "+value+""); response.setHeader(key, value); } } else if (responseHeaderEncoding==HeaderEncoding.NONE) { response.setHeader(key, value); } else if (responseHeaderEncoding==HeaderEncoding.HTML_ESCAPE) { response.setHeader(key, HtmlEscape.escapeSpecial(value)); } } @SuppressWarnings("unchecked") private K newInstance(Class clazz) throws UniversalStatementException { // Costruisco la classe; Constructor costructor=null; try { costructor = clazz.getConstructor((Class[])null); } catch (SecurityException e) { throw new UniversalStatementException("SecurityException with class costructor for "+clazz,e); } catch (NoSuchMethodException e) { throw new UniversalStatementException("NoSuchMethodException with class costructor for "+clazz, e); } try { return (K)costructor.newInstance((Object[])null); } catch (IllegalArgumentException e) { throw new UniversalStatementException("IllegalArgumentException with class costructor for "+clazz, e); } catch (InstantiationException e) { throw new UniversalStatementException("InstantiationException with class costructor for "+clazz, e); } catch (IllegalAccessException e) { throw new UniversalStatementException("IllegalAccessException with class costructor for "+clazz, e); } catch (InvocationTargetException e) { throw new UniversalStatementException("InvocationTargetException with class costructor for "+clazz, e); } } public HeaderEncoding getResponseHeaderEncoding() { return responseHeaderEncoding; } }