/** * Copyright 2008-2016 Qualogy Solutions B.V. * * 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 com.qualogy.qafe.business.integration; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import com.qualogy.qafe.bind.commons.type.Parameter; import com.qualogy.qafe.bind.core.application.ApplicationContext; import com.qualogy.qafe.bind.integration.service.Method; import com.qualogy.qafe.bind.integration.service.Service; import com.qualogy.qafe.bind.integration.service.ServiceRef; import com.qualogy.qafe.business.integration.adapter.AdaptedToService; import com.qualogy.qafe.business.integration.adapter.Adapter; import com.qualogy.qafe.business.integration.adapter.UnableToAdaptException; import com.qualogy.qafe.business.integration.filter.Filters; import com.qualogy.qafe.business.integration.filter.page.Page; import com.qualogy.qafe.business.integration.filter.page.PageCreator; import com.qualogy.qafe.business.integration.filter.sort.Sort; import com.qualogy.qafe.business.integration.filter.sort.SortCreator; import com.qualogy.qafe.business.resource.Resource; import com.qualogy.qafe.business.resource.ResourcePool; import com.qualogy.qafe.business.resource.java.JavaClass; import com.qualogy.qafe.core.datastore.CacheHandler; import com.qualogy.qafe.core.datastore.DataIdentifier; import com.qualogy.qafe.core.datastore.DataStore; import com.qualogy.qafe.core.errorhandling.ExternalException; import com.qualogy.qafe.core.framework.business.IntegrationProcessor; public abstract class Processor implements IntegrationProcessor { public final void process(ApplicationContext context, DataIdentifier dataId, ServiceRef serviceRef) throws ExternalException, UnableToAdaptException { Method method = serviceRef.getMethod(); if (method == null) { throw new IllegalArgumentException( "unknown method call in service reference [" + serviceRef.getId() + "]"); } ClassLoader classLoader = getClassLoader(context, serviceRef.getRef()); Map<String, AdaptedToService> serviceParams = Adapter.adaptIn(classLoader, context, dataId, method.getInput()); Filters filters = new Filters(); Page page = null; if (method.isScrollable()) { page = PageCreator.create(dataId); } Sort sort = SortCreator.create(dataId); filters.setPage(page); filters.setSort(sort); Object result = execute(context, serviceRef, method, serviceParams, filters, dataId); Adapter.adaptOut(dataId, result, method.getOutput()); performPostProcess(dataId, method, filters); } private Object execute(ApplicationContext context, ServiceRef serviceRef, Method method, Map<String, AdaptedToService> paramsIn, Filters filters, DataIdentifier dataId) throws ExternalException { Object result = null; String cacheToken = generateCacheToken(paramsIn, filters); String cacheKey = CacheHandler.getInstance().generateKey(context, serviceRef, cacheToken); if (CacheHandler.getInstance().hasCache(context, serviceRef, cacheToken)) { result = CacheHandler.getInstance().retrieve(cacheKey); } else { result = execute(context, serviceRef.getRef(), method, paramsIn, filters, dataId); if (CacheHandler.getInstance().isCached(serviceRef)) { CacheHandler.getInstance().store(cacheKey, result); } } return result; } private String generateCacheToken(Map<String, AdaptedToService> paramsIn, Filters filters) { StringBuffer cacheToken = new StringBuffer(); List<Object> inputParams = resolveInputParams(paramsIn); cacheToken.append(inputToString(inputParams)); String filterToString = filterToString(filters); if(filterToString != null) { cacheToken.append(filterToString); } return cacheToken.toString(); } private List<Object> resolveInputParams(Map<String, AdaptedToService> paramsIn) { List<Object> inputParamList = new ArrayList<Object>(); if (paramsIn != null) { Iterator<String> itrKey = paramsIn.keySet().iterator(); while (itrKey.hasNext()) { String key = itrKey.next(); AdaptedToService adaptedToService = paramsIn.get(key); if(adaptedToService != null) { inputParamList.add(key + "=" + adaptedToService.getValue()); } } } return inputParamList; } private String inputToString(List<Object> inputParams) { StringBuffer sb = new StringBuffer(); if (inputParams != null) { for (Object object : inputParams) { sb.append(object.toString()); sb.append(CacheHandler.KEY_DELIMITER); } } return sb.toString(); } protected String filterToString(Filters filters){ StringBuilder filterString = new StringBuilder(); if(filters != null) { Page page = filters.getPage(); if(page != null) { filterString.append(DataStore.KEY_WORD_PAGE_NUMBER + "=" + page.getOffset()); filterString.append(DataStore.KEY_WORD_PAGESIZE + "=" + page.getMaxRows()); } Sort sort = filters.getSort(); if(sort != null) { filterString.append(DataStore.KEY_WORD_SORT_ON_COLUMN + "=" + sort.getColumn()); filterString.append(DataStore.KEY_WORD_SORT_ORDER + "=" + sort.getSortOrder()); } } return filterString.toString(); } protected void performPostProcess(DataIdentifier dataId, Method method, Filters filters) throws ExternalException { postProcess(dataId, method, filters); if ((filters != null) && (filters.getPage() != null)) { // It could be that the method does not have output parameters, // even when paging is enabled if (method.getOutput() == null) { return; } // Store the new value of page number, so it can be saved back to the datagrid, // if no data is present the page number is set to null so the datagrid should take care of it for (Iterator iter1=method.getOutput().iterator(); iter1.hasNext();) { Parameter param = (Parameter) iter1.next(); if (param.getName() != null) { Object value = DataStore.getValue(dataId, param.getName()); Integer actualPageNumber = filters.getPage().getOffset(); if ((value == null) || ((value instanceof List) && (((List) value).isEmpty()))) { actualPageNumber = null; } DataStore.store(dataId, DataStore.KEY_WORD_PAGE_NUMBER, actualPageNumber); } } } } /** * Subclasses should overwrite this method for post processing (filtering) */ protected void postProcess(DataIdentifier dataId, Method method, Filters filters) throws ExternalException { } private ClassLoader getClassLoader(ApplicationContext context, Service service) { Resource resource = getResource(context, service); ClassLoader classLoader = null; if (resource instanceof JavaClass && (((JavaClass) resource).getExternalClassLoader() != null)) { classLoader = ((JavaClass) resource).getExternalClassLoader(); } else { classLoader = this.getClass().getClassLoader(); } return classLoader; } private Resource getResource(ApplicationContext context, Service service) { return ResourcePool.getInstance() .get(context.getId(), service.getResourceRef().getRef().getId()); } /** * expecting a non-null params list * * @param context * @param service * @param method * @param paramsIn * @param filters * @return * @throws ExternalException */ protected abstract Object execute(ApplicationContext context, Service service, Method method, Map<String, AdaptedToService> paramsIn, Filters filters, DataIdentifier dataId) throws ExternalException; }