001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.automation.client.jaxrs.spi;
020
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.Date;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Map;
027
028import org.nuxeo.ecm.automation.client.OperationRequest;
029import org.nuxeo.ecm.automation.client.model.DateUtils;
030import org.nuxeo.ecm.automation.client.model.OperationDocumentation;
031import org.nuxeo.ecm.automation.client.model.OperationDocumentation.Param;
032import org.nuxeo.ecm.automation.client.model.OperationInput;
033
034/**
035 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
036 */
037public class JavaOperationRequest implements OperationRequest {
038
039    protected final OperationDocumentation op;
040
041    protected final JavaSession session;
042
043    protected final Map<String, Object> params;
044
045    protected final Map<String, Object> ctx;
046
047    protected final Map<String, String> headers;
048
049    protected Object input;
050
051    public JavaOperationRequest(JavaSession session, OperationDocumentation op) {
052        this(session, op, new HashMap<String, Object>());
053    }
054
055    public JavaOperationRequest(JavaSession session, OperationDocumentation op, Map<String, Object> ctx) {
056        this.session = session;
057        this.op = op;
058        params = new HashMap<String, Object>();
059        headers = new HashMap<String, String>();
060        this.ctx = ctx;
061    }
062
063    public JavaSession getSession() {
064        return session;
065    }
066
067    protected final boolean acceptInput(String type) {
068        for (int i = 0, size = op.signature.length; i < size; i += 2) {
069            if ("void".equals(op.signature[i])) {
070                return true;
071            }
072            if (type.equals(op.signature[i])) {
073                return true;
074            }
075        }
076        return false;
077    }
078
079    protected final void checkInput(String type) {
080        if (!acceptInput(type)) {
081            throw new IllegalArgumentException("Input not supported: " + type);
082        }
083    }
084
085    public List<String> getParamNames() {
086        List<String> result = new ArrayList<String>();
087        for (Param param : op.params) {
088            result.add(param.name);
089        }
090        return result;
091    }
092
093    public Param getParam(String key) {
094        for (Param param : op.params) {
095            if (key.equals(param.name)) {
096                return param;
097            }
098        }
099        return null;
100    }
101
102    public OperationRequest setInput(Object input) {
103        if (input == null) {
104            checkInput("void");
105        } else if (input instanceof OperationInput) {
106            checkInput(((OperationInput) input).getInputType());
107        }
108        this.input = input;
109        return this;
110    }
111
112    public Object getInput() {
113        return input;
114    }
115
116    public String getUrl() {
117        return session.getClient().getBaseUrl() + op.url;
118    }
119
120    public OperationRequest set(String key, Object value) {
121        Param param = getParam(key);
122        if (param == null) {
123            throw new IllegalArgumentException("No such parameter '" + key + "' for operation " + op.id
124                    + ".\n\tAvailable params: " + getParamNames());
125        }
126        if (value == null) {
127            params.remove(key);
128            return this;
129        }
130        // handle strings and primitive differently
131        // TODO
132        // if (!param.type.equals(value.getParamType())) {
133        // throw new
134        // IllegalArgumentException("Invalid parameter type:
135        // "+value.getParamType());
136        // }
137        if (value.getClass() == Date.class) {
138            params.put(key, DateUtils.formatDate((Date) value));
139        } else {
140            params.put(key, value.toString());
141        }
142        return this;
143    }
144
145    public OperationRequest setContextProperty(String key, Object value) {
146        ctx.put(key, value != null ? value.toString() : null);
147        return this;
148    }
149
150    public Map<String, Object> getContextParameters() {
151        return ctx;
152    }
153
154    public Map<String, Object> getParameters() {
155        return params;
156    }
157
158    public Object execute() throws IOException {
159        return session.execute(this);
160    }
161
162    public OperationRequest setHeader(String key, String value) {
163        headers.put(key, value);
164        return this;
165    }
166
167    public Map<String, String> getHeaders() {
168        return headers;
169    }
170
171    @Override
172    public OperationDocumentation getOperation() {
173        return op;
174    }
175
176}