/** * Copyright 2012 Couchbase, Inc. * * 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 org.couchbase.mock.views; import java.util.ArrayList; import java.util.Map; import java.util.Set; import javax.script.ScriptException; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import org.couchbase.mock.JsonUtils; /** * @author Mark Nunberg * @author Sergey Avseyev */ public class DesignDocument { final private String body; private String id; final private ArrayList<View> views; private DesignDocument(String body) { this.body = body; this.views = new ArrayList<View>(); } /** * Create a new design document * @param body The JSON encoded source of this design document * @param name The name of the design document. This should be the simple name, e.g. {@code beer}. If the * {@code body} contains a {@code _id} property, then that property will override * {@code name} * @return A new design document * @throws DesignParseException */ public static DesignDocument create(String body, String name) throws DesignParseException { DesignDocument doc = new DesignDocument(body); doc.id = "_design/" + name; doc.load(); return doc; } private void load() throws DesignParseException { try { JsonObject obj = JsonUtils.GSON.fromJson(body, JsonObject.class); if (obj.has("_id")) { this.id = obj.get("_id").getAsString(); } if (this.id == null) { throw new DesignParseException("No _id specified and no implicit path provided"); } JsonObject viewsJson = obj.getAsJsonObject("views"); if (viewsJson == null) { throw new DesignParseException("Missing `views`"); } for (Map.Entry<String,JsonElement> entry : viewsJson.entrySet()) { JsonElement curElem = entry.getValue(); if (!curElem.isJsonObject()) { throw new DesignParseException("View contents must be a JSON dictionary"); } JsonObject view = curElem.getAsJsonObject(); if (!view.has("map")) { throw new DesignParseException("Missing `map` function"); } String mapSrc = view.get("map").getAsString(); String reduceSrc = null; if (view.has("reduce")) { reduceSrc = view.get("reduce").getAsString(); } views.add(new View(entry.getKey(), mapSrc, reduceSrc)); } } catch (ScriptException ex) { throw new DesignParseException(ex); } catch (JsonParseException ex) { throw new DesignParseException(ex); } } /** * @return Get the raw JSON string from which this design was constructed */ public String getBody() { return body; } /** * Get the name of the design document * @return A string in the form of {@code _design/$name} */ public String getId() { return id; } /** * Get a list of views contained within this design document * @return The list of views */ public ArrayList<View> getViews() { return views; } }