001/*
002 * Copyright (C) 2014 Jörg Prante
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.xbib.elasticsearch.plugin.jdbc.state;
017
018import org.elasticsearch.ElasticsearchParseException;
019import org.elasticsearch.cluster.metadata.MetaData;
020import org.elasticsearch.common.collect.ImmutableList;
021import org.elasticsearch.common.io.stream.StreamInput;
022import org.elasticsearch.common.io.stream.StreamOutput;
023import org.elasticsearch.common.xcontent.ToXContent;
024import org.elasticsearch.common.xcontent.XContentBuilder;
025import org.elasticsearch.common.xcontent.XContentParser;
026
027import java.io.IOException;
028import java.util.List;
029
030import static org.elasticsearch.common.collect.Lists.newLinkedList;
031
032/**
033 * Contains metadata about registered rivers
034 */
035public class RiverStatesMetaData implements MetaData.Custom {
036
037    public static final String TYPE = "riverstates";
038
039    public static final Factory FACTORY = new Factory();
040
041    private final ImmutableList<RiverState> riverStates;
042
043    /**
044     * Constructs new river state metadata
045     *
046     * @param riverStates list of river states
047     */
048    public RiverStatesMetaData(RiverState... riverStates) {
049        this.riverStates = ImmutableList.copyOf(riverStates);
050    }
051
052    /**
053     * Returns list of current river states
054     *
055     * @return list of river states
056     */
057    public ImmutableList<RiverState> getRiverStates() {
058        return this.riverStates;
059    }
060
061    /**
062     * Returns a river state with a given name or null if such river doesn't exist
063     *
064     * @param name name of river
065     * @return river metadata
066     */
067    public ImmutableList<RiverState> getRiverStates(String name, String type) {
068        ImmutableList.Builder<RiverState> riverStatesBuilder = ImmutableList.builder();
069        for (RiverState riverState : riverStates) {
070            if (("*".equals(name) || name.equals(riverState.getName())) &&
071                    ("*".equals(type) || type.equals(riverState.getType()))) {
072                riverStatesBuilder.add(riverState);
073            }
074        }
075        return riverStatesBuilder.build();
076    }
077
078    /**
079     * River state metadata factory
080     */
081    public static class Factory implements MetaData.Custom.Factory<RiverStatesMetaData> {
082
083        @Override
084        public String type() {
085            return TYPE;
086        }
087
088        @Override
089        public RiverStatesMetaData readFrom(StreamInput in) throws IOException {
090            RiverState[] river = new RiverState[in.readVInt()];
091            for (int i = 0; i < river.length; i++) {
092                river[i] = new RiverState();
093                river[i].readFrom(in);
094            }
095            return new RiverStatesMetaData(river);
096        }
097
098        @Override
099        public void writeTo(RiverStatesMetaData riverStatesMetaData, StreamOutput out) throws IOException {
100            out.writeVInt(riverStatesMetaData.getRiverStates().size());
101            for (RiverState river : riverStatesMetaData.getRiverStates()) {
102                river.writeTo(out);
103            }
104        }
105
106        @Override
107        public RiverStatesMetaData fromXContent(XContentParser parser) throws IOException {
108            XContentParser.Token token = parser.nextToken();
109            List<RiverState> riverStateList = newLinkedList();
110            if (token == XContentParser.Token.FIELD_NAME) {
111                String name = parser.currentName();
112                if (parser.nextToken() != XContentParser.Token.START_ARRAY) {
113                    throw new ElasticsearchParseException("failed to parse river state at [" + name + "], expected array");
114                }
115            }
116            while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
117                RiverState riverState = new RiverState();
118                riverState.fromXContent(parser);
119                riverStateList.add(riverState);
120            }
121            return new RiverStatesMetaData(riverStateList.toArray(new RiverState[riverStateList.size()]));
122        }
123
124        @Override
125        public void toXContent(RiverStatesMetaData riverStatesMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
126            builder.startArray("states");
127            for (RiverState riverState : riverStatesMetaData.getRiverStates()) {
128                riverState.toXContent(builder, params);
129            }
130            builder.endArray();
131        }
132
133        @Override
134        public boolean isPersistent() {
135            return true;
136        }
137
138    }
139
140}