001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.ecm.automation.client.jaxrs.spi;
013
014import java.io.IOException;
015import java.text.SimpleDateFormat;
016import java.util.ArrayList;
017import java.util.Calendar;
018import java.util.Date;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.nuxeo.ecm.automation.client.OperationRequest;
024import org.nuxeo.ecm.automation.client.model.DateUtils;
025import org.nuxeo.ecm.automation.client.model.Document;
026import org.nuxeo.ecm.automation.client.model.OperationDocumentation;
027import org.nuxeo.ecm.automation.client.model.OperationDocumentation.Param;
028import org.nuxeo.ecm.automation.client.model.OperationInput;
029
030/**
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 */
033public class DefaultOperationRequest implements OperationRequest {
034
035    protected final OperationDocumentation op;
036
037    protected final DefaultSession session;
038
039    protected final Map<String, Object> params;
040
041    protected final Map<String, Object> ctx;
042
043    protected final Map<String, String> headers;
044
045    protected Object input;
046
047    public DefaultOperationRequest(DefaultSession session, OperationDocumentation op) {
048        this(session, op, new HashMap<String, Object>());
049    }
050
051    public DefaultOperationRequest(DefaultSession session, OperationDocumentation op, Map<String, Object> ctx) {
052        this.session = session;
053        this.op = op;
054        params = new HashMap<String, Object>();
055        headers = new HashMap<String, String>();
056        this.ctx = ctx;
057    }
058
059    public DefaultSession getSession() {
060        return session;
061    }
062
063    protected final boolean acceptInput(String type) {
064        for (int i = 0, size = op.signature.length; i < size; i += 2) {
065            if ("void".equals(op.signature[i])) {
066                return true;
067            }
068            if (type.equals(op.signature[i])) {
069                return true;
070            }
071        }
072        return false;
073    }
074
075    protected final void checkInput(String type) {
076        if (!acceptInput(type)) {
077            throw new IllegalArgumentException("Input not supported: " + type + " for the operation: " + op.id);
078        }
079    }
080
081    public List<String> getParamNames() {
082        List<String> result = new ArrayList<String>();
083        for (Param param : op.params) {
084            result.add(param.name);
085        }
086        return result;
087    }
088
089    public Param getParam(String key) {
090        for (Param param : op.params) {
091            if (key.equals(param.name)) {
092                return param;
093            }
094        }
095        return null;
096    }
097
098    public OperationRequest setInput(Object input) {
099        if (input == null) {
100            checkInput("void");
101        } else if (input instanceof OperationInput) {
102            checkInput(((OperationInput) input).getInputType());
103        }
104        this.input = input;
105        return this;
106    }
107
108    public Object getInput() {
109        return input;
110    }
111
112    public String getUrl() {
113        return session.getClient().getBaseUrl() + op.url;
114    }
115
116    public OperationRequest set(String key, Object value) {
117        Param param = getParam(key);
118        if (param == null) {
119            throw new IllegalArgumentException("No such parameter '" + key + "' for operation " + op.id
120                    + ".\n\tAvailable params: " + getParamNames());
121        }
122        if (value == null) {
123            params.remove(key);
124            return this;
125        }
126        // handle strings and primitive differently
127        // TODO
128        // if (!param.type.equals(value.getParamType())) {
129        // throw new
130        // IllegalArgumentException("Invalid parameter type:
131        // "+value.getParamType());
132        // }
133        if (value.getClass() == Date.class) {
134            params.put(key, DateUtils.formatDate((Date) value));
135        } else if (value instanceof Calendar){
136            params.put(key, DateUtils.formatDate(((Calendar) value).getTime()));
137        } else if ("properties".equals(key) && value instanceof Document) {
138            // Handle document parameter in case of properties - and bind it to
139            // properties
140            List<Param> parameters = op.getParams();
141            for (Param parameter : parameters) {
142                // Check if one of params has the Properties type
143                if ("properties".equals(parameter.getType())) {
144                    params.put("properties", ((Document) value).getDirties().toString());
145                }
146            }
147        } else {
148            params.put(key, value);
149        }
150        return this;
151    }
152
153    public OperationRequest setContextProperty(String key, Object value) {
154        ctx.put(key, value != null ? value : null);
155        return this;
156    }
157
158    public Map<String, Object> getContextParameters() {
159        return ctx;
160    }
161
162    public Map<String, Object> getParameters() {
163        return params;
164    }
165
166    public Object execute() throws IOException {
167        return session.execute(this);
168    }
169
170    public OperationRequest setHeader(String key, String value) {
171        headers.put(key, value);
172        return this;
173    }
174
175    public Map<String, String> getHeaders() {
176        return headers;
177    }
178
179    @Override
180    public OperationDocumentation getOperation() {
181        return op;
182    }
183}