001/*
002 * ModeShape (http://www.modeshape.org)
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 */
016package org.modeshape.jdbc.rest;
017
018import java.util.HashMap;
019import java.util.HashSet;
020import java.util.Iterator;
021import java.util.LinkedHashMap;
022import java.util.Map;
023import java.util.Set;
024import org.codehaus.jettison.json.JSONArray;
025import org.codehaus.jettison.json.JSONException;
026import org.codehaus.jettison.json.JSONObject;
027
028/**
029 * POJO which can unmarshal the {@link org.codehaus.jettison.json.JSONObject} representation of a list of repositories coming
030 * from a ModeShape REST Service.
031 *
032 * @author Horia Chiorean (hchiorea@redhat.com)
033 */
034public final class Repositories implements Iterable<Repositories.Repository> {
035
036    private static final String KEY_REPOSITORIES = "repositories";
037    private static final String KEY_NAME = "name";
038
039    private final Map<String, Repository> repositories;
040
041    /**
042     * Creates a new instance wrapping the JSON data.
043     *
044     * @param json a {@link org.codehaus.jettison.json.JSONObject} coming from the REST server; never {@code null}
045     */
046    protected Repositories( JSONObject json ) {
047        try {
048            if (!json.has(KEY_REPOSITORIES)) {
049                throw new IllegalArgumentException("Invalid JSON object: " + json);
050            }
051            JSONArray repositoriesJSON = json.getJSONArray(KEY_REPOSITORIES);
052            int length = repositoriesJSON.length();
053            this.repositories = new HashMap<>(length);
054            for (int i = 0; i < length; i++) {
055                JSONObject repositoryJSON = repositoriesJSON.getJSONObject(i);
056                Repository repository = new Repository(repositoryJSON);
057                repositories.put(repository.getName(), repository);
058            }
059        } catch (JSONException e) {
060            throw new RuntimeException(e);
061        }
062    }
063
064    @Override
065    public Iterator<Repository> iterator() {
066        return repositories.values().iterator();
067    }
068
069    /**
070     * Returns the list of repositories this container holds.
071     *
072     * @return a {@code List(Repository)}, never {@code null}
073     */
074    public Set<Repository> getRepositories() {
075        return new HashSet<>(repositories.values());
076    }
077
078    /**
079     * Returns a list of all the repository names.
080     *
081     * @return a {@code Set} of names, never {@code null}
082     */
083    public Set<String> getRepositoryNames() {
084        return new HashSet<>(repositories.keySet());
085    }
086
087    /**
088     * Returns a repository with the given name from the list of contained repositories.
089     *
090     * @param name a {@code String} the name of the repository to look for; never {@code null}
091     * @return either a {@link Repositories.Repository} instance or {@code null} if
092     * there is no such repository.
093     */
094    public Repository getRepository(String name) {
095        return repositories.get(name);
096    }
097
098    /**
099     * POJO representation of a {@link javax.jcr.Repository}
100     */
101    public static final class Repository {
102        private final String name;
103        private final Map<String, Object> metadata;
104        private final int activeSessionsCount;
105
106        @SuppressWarnings( "unchecked" )
107        protected Repository( JSONObject object ) {
108            try {
109                this.name = object.getString(KEY_NAME);
110                this.activeSessionsCount = object.has("activeSessionsCount") ? object.getInt("activeSessionsCount") : 0;
111                this.metadata = new LinkedHashMap<>();
112                if (object.has("metadata")) {
113                    JSONObject metadataObject = object.getJSONObject("metadata");
114                    for (Iterator<String> keysIterator = metadataObject.keys(); keysIterator.hasNext(); ) {
115                        String key = keysIterator.next();
116                        Object value = metadataObject.get(key);
117                        if (value instanceof JSONArray) {
118                            JSONArray array = (JSONArray)value;
119                            String[] strings = new String[array.length()];
120                            for (int i = 0; i < array.length(); i++) {
121                                strings[i] = array.get(i).toString();
122                            }
123                            this.metadata.put(key, strings);
124                        } else {
125                            this.metadata.put(key, value.toString());
126                        }
127                    }
128                }
129            } catch (JSONException e) {
130                throw new RuntimeException(e);
131            }
132        }
133
134        /**
135         * Returns the name of the repository.
136         *
137         * @return a {@code String}, never {@code null}
138         */
139        public String getName() {
140            return name;
141        }
142
143        /**
144         * Returns the repository metadata, if any.
145         *
146         * @return a {@code Map(metadataKey, metadataValue)}, never {@code null}
147         */
148        public Map<String, Object> getMetadata() {
149            return metadata;
150        }
151
152        /**
153         * Returns the number of active sessions on this repository.
154         *
155         * @return an {@code int}, never negative.
156         */
157        public int getActiveSessionsCount() {
158            return activeSessionsCount;
159        }
160    }
161}