/** * <copyright> * * Copyright (c) 2009, 2010 Springsite BV (The Netherlands) and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Martin Taal - Initial API and implementation * Dzmitry [zmicer] Harachka - implementation * </copyright> * * $Id: ModelOperation.java,v 1.6 2011/08/29 05:22:24 mtaal Exp $ */ package org.eclipse.emf.texo.server.service; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.emf.texo.component.ComponentProvider; import org.eclipse.emf.texo.component.TexoComponent; import org.eclipse.emf.texo.json.JSONValueConverter; import org.eclipse.emf.texo.server.model.request.Parameter; import org.eclipse.emf.texo.server.model.request.QueryType; import org.eclipse.emf.texo.server.model.request.RequestModelPackage; import org.eclipse.emf.texo.store.ObjectStore; /** * The base abstract class for model operations. Model operations can for example be crud operations on model instances. * * @author <a href="mailto:zmicer.harachka@gmail.com">Dzmitry [zmicer] Harachka</a> * @author <a href="mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.6 $ */ public abstract class ModelOperation implements TexoComponent { private static final String FALSE = Boolean.FALSE.toString(); private ServiceContext serviceContext; /** * Execute the model operation, if an object store is set then the operation is executed within an object store * transaction. The {@link ObjectStore#begin()} method is called before the operation, {@link ObjectStore#commit()} is * called after the operation. * * This method calls the method {@link ModelOperation#internalExecute()} which is implemented by a specific subclass. * * If an exception occurs the transaction is rolledback ({@link ObjectStore#rollback()} and an error result is * returned (see {@link ServiceContext#createErrorResult(Throwable)}). */ public void execute() { try { if (getObjectStore() != null) { getObjectStore().begin(); } internalExecute(); if (getObjectStore() != null) { getObjectStore().commit(); } } catch (Throwable t) { t.printStackTrace(System.err); getServiceContext().createErrorResult(t); if (getObjectStore() != null) { getObjectStore().rollback(); } } } /** * Method implemented by the subclass to actually execute the operation. */ protected abstract void internalExecute(); public ServiceContext getServiceContext() { return serviceContext; } public void setServiceContext(ServiceContext serviceContext) { this.serviceContext = serviceContext; } public ObjectStore getObjectStore() { return getServiceContext().getObjectStore(); } protected QueryType getQueryType() { QueryType queryType = null; if (getServiceContext().getRequestContent() != null && getServiceContext().getRequestContent().trim().length() > 0) { final List<Object> requestData = getServiceContext().getRequestData(); for (Object object : requestData) { if (object instanceof QueryType) { queryType = (QueryType) object; break; } } } final boolean queryTypeFromContent = queryType != null; // 1) there is a query! final String namedQueryParam = (String) getServiceContext().getRequestParameters().get( ServiceConstants.PARAM_NAMEDQUERY); final String qryStrParam = (String) getServiceContext().getRequestParameters().get(ServiceConstants.PARAM_QUERY); if (queryType == null && qryStrParam != null && qryStrParam.trim().length() > 0) { getServiceContext().getServiceOptions().checkFalse(ServiceOptions.OPTION_ALLOW_RETRIEVE_QUERIES); queryType = RequestModelPackage.INSTANCE.getModelFactory().createQueryType(); queryType.setQuery(qryStrParam); } else if (queryType == null && namedQueryParam != null) { queryType = RequestModelPackage.INSTANCE.getModelFactory().createQueryType(); queryType.setNamedQuery(namedQueryParam); } if (queryType == null) { return queryType; } if (!queryTypeFromContent) { queryType.setFirstResult(getFirstResult()); queryType.setMaxResults(getMaxResults()); final String noCountParam = (String) getServiceContext().getRequestParameters().get( ServiceConstants.PARAM_NO_COUNT); queryType.setDoCount(noCountParam == null || FALSE.equals(noCountParam)); } if (queryType.getQuery() != null) { // check the query ComponentProvider.getInstance().newInstance(QueryChecker.class).checkQuery(queryType.getQuery()); } // if there is no limit on the max results then don't count if (queryType.getMaxResults() == -1) { queryType.setDoCount(false); } return queryType; } protected Map<String, Object> getParameters(QueryType queryType) { final Map<String, Object> result = new HashMap<String, Object>(); // get the queryparameters from the request for (String key : getServiceContext().getRequestParameters().keySet()) { if (key.startsWith(ServiceConstants.QUERY_PARAM_PREFIX)) { final Object value = getServiceContext().getRequestParameters().get(key); final String name = key.substring(ServiceConstants.QUERY_PARAM_PREFIX.length()); result.put(name, value); } } if (queryType == null) { return result; } final JSONValueConverter converter = ComponentProvider.getInstance().newInstance(JSONValueConverter.class); for (Parameter parameter : queryType.getParameters()) { final String type = parameter.getType(); Object value = parameter.getValue(); if (type != null) { if ("date".equals(type)) { //$NON-NLS-1$ value = converter.createDateFromJSON(value); } else if ("dateTime".equals(type)) { //$NON-NLS-1$ value = converter.createDateTimeFromJSON(value); } else { value = converter.createTimeFromJSON(value); } } result.put(parameter.getName(), value); } return result; } protected int getFirstResult() { return getNumberParameter(ServiceConstants.PARAM_FIRST_RESULT); } protected int getMaxResults() { return getNumberParameter(ServiceConstants.PARAM_MAX_RESULTS); } private int getNumberParameter(String paramName) { if (getServiceContext().getRequestParameters().containsKey(paramName)) { try { return Integer.parseInt((String) getServiceContext().getRequestParameters().get(paramName)); } catch (NumberFormatException e) { // ignore on purpose return -1; } } return -1; } /** * Closes the underlying objectstore, if it was set. */ public void close() { if (getObjectStore() != null) { getObjectStore().close(); } } }