/******************************************************************************* * Copyright (c) 2015 hangum. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * hangum - initial API and implementation ******************************************************************************/ package com.hangum.tadpole.engine.restful; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URLDecoder; import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.hangum.tadpole.commons.libs.core.utils.VelocityUtils; import com.hangum.tadpole.commons.util.DateUtil; import com.hangum.tadpole.engine.sql.paremeter.lang.OracleStyleSQLNamedParameterUtil; import com.hangum.tadpole.preference.define.GetAdminPreference; /** * RESTful API UTILS * * @author hangum * */ public class RESTfulAPIUtils { private static final Logger logger = Logger.getLogger(RESTfulAPIUtils.class); /** define variable */ public enum TDB_DATA_TYPE {_VARCHAR, _BIT, _NUM, _TINYINT, _SMALLINT, _INT, _BIGINT, _FLOAT, _DOUBLE, _VARBINARY, _DATE, _TIME}; /** * make original sql * * @param strName * @param strSQLs * @param strArgument * @return */ public static String makeTemplateTOSQL(String strName, String strSQLs, String strArgument) throws SQLTemplateException { String strResult = ""; try { Map<String, Object> params = RESTfulAPIUtils.maekArgumentTOMap(strArgument); strResult = VelocityUtils.getTemplate(strName, strSQLs, params); if(logger.isDebugEnabled()) logger.debug(strResult); } catch(Exception e) { logger.error("Make Template", e); throw new SQLTemplateException(e.getMessage()); } return strResult; } /** * make argument to map * @param strArgument * @return * @throws UnsupportedEncodingException */ public static Map<String, Object> maekArgumentTOMap(String strArgument) throws RESTFULUnsupportedEncodingException { if(StringUtils.split(strArgument, "&") == null) return new HashMap<String, Object>(); if(logger.isDebugEnabled()) logger.debug("original URL is ===> " + strArgument); Map<String, Object> params = new HashMap<String, Object>(); try { for (String param : StringUtils.split(strArgument, "&")) { String pair[] = StringUtils.split(param, "="); String key = URLDecoder.decode(pair[0], "UTF-8"); Object value = null; if (pair.length > 1) { try { value = convertExistObject(key, pair[1]); } catch(Exception e) { value = pair[1]; } } params.put(key, value); } } catch (UnsupportedEncodingException e1) { throw new RESTFULUnsupportedEncodingException(e1); } return params; } /** * * @param variableType * @param value * @return * @throws UnsupportedEncodingException */ public static Object convertExistObject(String variableType, String value) throws UnsupportedEncodingException { value = URLDecoder.decode(value, "UTF-8"); if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._BIT.name())) { return new Boolean(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._NUM.name())) { return new BigDecimal(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._TINYINT.name())) { return new Byte(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._SMALLINT.name())) { return new Short(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._INT.name())) { return new Integer(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._BIGINT.name())) { return new Long(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._FLOAT.name())) { return new Float(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._DOUBLE.name())) { return new Double(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._VARBINARY.name())) { return new Byte(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._DATE.name())) { return DateUtil.convertToDate(value); } else if(StringUtils.startsWithIgnoreCase(variableType, TDB_DATA_TYPE._TIME.name())) { return new Timestamp(new Long(value).longValue()); } return value; } /** * Return oracle style argument to java list * * @param mapIndex * @param strArgument * @return * @throws RESTFulArgumentNotMatchException * @throws UnsupportedEncodingException */ public static List<Object> makeArgumentToOracleList(Map<Integer, String> mapIndex, String strArgument) throws RESTFulArgumentNotMatchException, RESTFULUnsupportedEncodingException { List<Object> listParam = new ArrayList<Object>(); Map<String, Object> params = maekArgumentTOMap(strArgument); for(int i=1; i<=mapIndex.size(); i++ ) { String strKey = mapIndex.get(i); if(!params.containsKey(strKey)) { throw new RESTFulArgumentNotMatchException("SQL Parameter not found. Must have to key name is " + strKey); } else { listParam.add( params.get(strKey) ); } } return listParam; } /** * return argument to java list * * @param strArgument * @return * @throws UnsupportedEncodingException */ public static List<Object> makeArgumentToJavaList(String strArgument) throws RESTFULUnsupportedEncodingException { List<Object> listParam = new ArrayList<Object>(); Map<String, Object> params = maekArgumentTOMap(strArgument); // assume this count... no way i'll argument is over 100..... --;; for(int i=1; i<100; i++) { if(params.containsKey(String.valueOf(i))) { listParam.add(params.get(""+i)); } else { break; } } return listParam; } /** * Return SQL Paramter * * @param strSQL * @return */ public static String getParameter(String strSQL) { if("".equals(strSQL)) return ""; String strArguments = ""; OracleStyleSQLNamedParameterUtil oracleNamedParamUtil = new OracleStyleSQLNamedParameterUtil(); oracleNamedParamUtil.parse(strSQL); Map<Integer, String> mapIndex = oracleNamedParamUtil.getMapIndexToName(); if(!mapIndex.isEmpty()) { for(String strParam : mapIndex.values()) { strArguments += String.format("%s={%s}&", strParam, strParam); } strArguments = StringUtils.removeEnd(strArguments, "&"); } else { strArguments = "";//1={FirstParameter}&2={SecondParameter}"; } return strArguments; } /** * make url * * @param strSQL * @param strRestURL * @return */ public static String makeURL(String strSQL, String strRestURL) { String strServerURL = GetAdminPreference.getApiServerURL(); return String.format("%s%s?%s", strServerURL, strRestURL, getParameter(strSQL)); } /** * user validate * * @param url * @return */ public static boolean validateURL(String url) { Pattern p = Pattern.compile("[/][-A-Za-z0-9+&@#/%=~_()|]{2}", Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(url); return m.find(); } }