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.util.ArrayList;
016import java.util.Date;
017import java.util.HashMap;
018import java.util.List;
019import java.util.Map;
020
021import org.nuxeo.ecm.automation.client.OperationRequest;
022import org.nuxeo.ecm.automation.client.model.DateUtils;
023import org.nuxeo.ecm.automation.client.model.OperationDocumentation;
024import org.nuxeo.ecm.automation.client.model.OperationDocumentation.Param;
025import org.nuxeo.ecm.automation.client.model.OperationInput;
026
027/**
028 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
029 */
030public class JavaOperationRequest implements OperationRequest {
031
032    protected final OperationDocumentation op;
033
034    protected final JavaSession session;
035
036    protected final Map<String, Object> params;
037
038    protected final Map<String, Object> ctx;
039
040    protected final Map<String, String> headers;
041
042    protected Object input;
043
044    public JavaOperationRequest(JavaSession session, OperationDocumentation op) {
045        this(session, op, new HashMap<String, Object>());
046    }
047
048    public JavaOperationRequest(JavaSession session, OperationDocumentation op, Map<String, Object> ctx) {
049        this.session = session;
050        this.op = op;
051        params = new HashMap<String, Object>();
052        headers = new HashMap<String, String>();
053        this.ctx = ctx;
054    }
055
056    public JavaSession getSession() {
057        return session;
058    }
059
060    protected final boolean acceptInput(String type) {
061        for (int i = 0, size = op.signature.length; i < size; i += 2) {
062            if ("void".equals(op.signature[i])) {
063                return true;
064            }
065            if (type.equals(op.signature[i])) {
066                return true;
067            }
068        }
069        return false;
070    }
071
072    protected final void checkInput(String type) {
073        if (!acceptInput(type)) {
074            throw new IllegalArgumentException("Input not supported: " + type);
075        }
076    }
077
078    public List<String> getParamNames() {
079        List<String> result = new ArrayList<String>();
080        for (Param param : op.params) {
081            result.add(param.name);
082        }
083        return result;
084    }
085
086    public Param getParam(String key) {
087        for (Param param : op.params) {
088            if (key.equals(param.name)) {
089                return param;
090            }
091        }
092        return null;
093    }
094
095    public OperationRequest setInput(Object input) {
096        if (input == null) {
097            checkInput("void");
098        } else if (input instanceof OperationInput) {
099            checkInput(((OperationInput) input).getInputType());
100        }
101        this.input = input;
102        return this;
103    }
104
105    public Object getInput() {
106        return input;
107    }
108
109    public String getUrl() {
110        return session.getClient().getBaseUrl() + op.url;
111    }
112
113    public OperationRequest set(String key, Object value) {
114        Param param = getParam(key);
115        if (param == null) {
116            throw new IllegalArgumentException("No such parameter '" + key + "' for operation " + op.id
117                    + ".\n\tAvailable params: " + getParamNames());
118        }
119        if (value == null) {
120            params.remove(key);
121            return this;
122        }
123        // handle strings and primitive differently
124        // TODO
125        // if (!param.type.equals(value.getParamType())) {
126        // throw new
127        // IllegalArgumentException("Invalid parameter type:
128        // "+value.getParamType());
129        // }
130        if (value.getClass() == Date.class) {
131            params.put(key, DateUtils.formatDate((Date) value));
132        } else {
133            params.put(key, value.toString());
134        }
135        return this;
136    }
137
138    public OperationRequest setContextProperty(String key, Object value) {
139        ctx.put(key, value != null ? value.toString() : null);
140        return this;
141    }
142
143    public Map<String, Object> getContextParameters() {
144        return ctx;
145    }
146
147    public Map<String, Object> getParameters() {
148        return params;
149    }
150
151    public Object execute() throws IOException {
152        return session.execute(this);
153    }
154
155    public OperationRequest setHeader(String key, String value) {
156        headers.put(key, value);
157        return this;
158    }
159
160    public Map<String, String> getHeaders() {
161        return headers;
162    }
163
164    @Override
165    public OperationDocumentation getOperation() {
166        return op;
167    }
168
169}