// Path: examples/translator/src/main/java/org/jboss/weld/vertx/examples/translator/Addresses.java
// public static final String CLEAR_CACHE = "org.jboss.weld.vertx.examples.translator.clear_cache";
// 
// Path: examples/translator/src/main/java/org/jboss/weld/vertx/examples/translator/Addresses.java
// public static final String REQUEST_DATA = "org.jboss.weld.vertx.examples.translator.request_data";
// 
// Path: core/src/main/java/org/jboss/weld/vertx/VertxEvent.java
// public interface VertxEvent {
// 
//     /**
//      * A failure code that is used if an observer method throws exception.
//      *
//      * @see Message#fail(int, String)
//      */
//     int OBSERVER_FAILURE_CODE = 0x1B00;
// 
//     /**
//      *
//      * @return the address the message was sent to
//      * @see Message#address()
//      */
//     String getAddress();
// 
//     /**
//      *
//      * @return the message headers
//      * @see Message#headers()
//      */
//     MultiMap getHeaders();
// 
//     /**
//      *
//      * @return the message body/payload
//      * @see Message#body()
//      */
//     Object getMessageBody();
// 
//     /**
//      *
//      * @return the reply address, or null in case of the message was sent without a reply handler
//      * @see Message#replyAddress()
//      */
//     String getReplyAddress();
// 
//     /**
//      * Set the reply to the message. Does not abort the processing of the event - other observer methods will be notified. The first reply set is passed to
//      * {@link Message#reply(Object)}.
//      * <p>
//      * If the reply address is null (point-to-point messaging without reply handler) the reply is ignored.
//      * </p>
//      * <p>
//      * An observer is encouraged to call {@link #fail(int, String)} if it needs to set the reply and this method returns <code>false</code>.
//      * </p>
//      *
//      * @param reply
//      * @see Message#reply(Object)
//      * @return <tt>true</tt> if the reply was sucessfully set
//      */
//     boolean setReply(Object reply);
// 
//     /**
//      * Aborts the processing of the event - no other observer methods will be called (unless the thrown {@link RecipientFailure} is swallowed).
//      *
//      * @param code
//      * @param message
//      * @see Message#fail(int, String)
//      * @throws RecipientFailure
//      */
//     void fail(int code, String message);
// 
//     /**
//      *
//      * @return <code>true</code> if a reply was previously set, <code>false</code> otherwise
//      * @see #setReply(Object)
//      */
//     boolean isReplied();
// 
//     /**
//      * Send/publish messages using the Vertx event bus.
//      *
//      * @param address
//      * @return a message
//      */
//     VertxMessage messageTo(String address);
// 
//     /**
//      *
//      * @author Martin Kouba
//      */
//     public interface VertxMessage {
// 
//         VertxMessage setDeliveryOptions(DeliveryOptions deliveryOptions);
// 
//         void send(Object message);
// 
//         void send(Object message, Handler<AsyncResult<Message<Object>>> replyHandler);
// 
//         void publish(Object message);
// 
//     }
// 
// }


import static org.jboss.weld.vertx.examples.translator.Addresses.CLEAR_CACHE;
import static org.jboss.weld.vertx.examples.translator.Addresses.REQUEST_DATA;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.jboss.weld.vertx.VertxConsumer;
import org.jboss.weld.vertx.VertxEvent;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2016, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.jboss.weld.vertx.examples.translator;






/**
 *
 * @author Martin Kouba
 */
@ApplicationScoped
public class DataCache {

    private static final Logger LOGGER = LoggerFactory.getLogger(DataCache.class.getName());

    private final Vertx vertx;

    private final ConcurrentMap<String, List<String>> cache;

    @Inject
    public DataCache(Vertx vertx) {
        this.cache = new ConcurrentHashMap<>();
        this.vertx = vertx;
    }

    void clear(@Observes @VertxConsumer(CLEAR_CACHE) VertxEvent event) {
        LOGGER.info("Clear dictionary cache");
        cache.clear();
    }

    /**
     *
     * @param word
     * @return a list of matching translations or <code>null</code> if no data available yet
     */
    List<String> getTranslations(String word) {
        List<String> translations = cache.get(word.toLowerCase());
        if (translations == null) {
            // No translations available - send request
            // We use synchronizer to block for 2 seconds
// Path: examples/translator/src/main/java/org/jboss/weld/vertx/examples/translator/Addresses.java
// public static final String CLEAR_CACHE = "org.jboss.weld.vertx.examples.translator.clear_cache";
// 
// Path: examples/translator/src/main/java/org/jboss/weld/vertx/examples/translator/Addresses.java
// public static final String REQUEST_DATA = "org.jboss.weld.vertx.examples.translator.request_data";
// 
// Path: core/src/main/java/org/jboss/weld/vertx/VertxEvent.java
// public interface VertxEvent {
// 
//     /**
//      * A failure code that is used if an observer method throws exception.
//      *
//      * @see Message#fail(int, String)
//      */
//     int OBSERVER_FAILURE_CODE = 0x1B00;
// 
//     /**
//      *
//      * @return the address the message was sent to
//      * @see Message#address()
//      */
//     String getAddress();
// 
//     /**
//      *
//      * @return the message headers
//      * @see Message#headers()
//      */
//     MultiMap getHeaders();
// 
//     /**
//      *
//      * @return the message body/payload
//      * @see Message#body()
//      */
//     Object getMessageBody();
// 
//     /**
//      *
//      * @return the reply address, or null in case of the message was sent without a reply handler
//      * @see Message#replyAddress()
//      */
//     String getReplyAddress();
// 
//     /**
//      * Set the reply to the message. Does not abort the processing of the event - other observer methods will be notified. The first reply set is passed to
//      * {@link Message#reply(Object)}.
//      * <p>
//      * If the reply address is null (point-to-point messaging without reply handler) the reply is ignored.
//      * </p>
//      * <p>
//      * An observer is encouraged to call {@link #fail(int, String)} if it needs to set the reply and this method returns <code>false</code>.
//      * </p>
//      *
//      * @param reply
//      * @see Message#reply(Object)
//      * @return <tt>true</tt> if the reply was sucessfully set
//      */
//     boolean setReply(Object reply);
// 
//     /**
//      * Aborts the processing of the event - no other observer methods will be called (unless the thrown {@link RecipientFailure} is swallowed).
//      *
//      * @param code
//      * @param message
//      * @see Message#fail(int, String)
//      * @throws RecipientFailure
//      */
//     void fail(int code, String message);
// 
//     /**
//      *
//      * @return <code>true</code> if a reply was previously set, <code>false</code> otherwise
//      * @see #setReply(Object)
//      */
//     boolean isReplied();
// 
//     /**
//      * Send/publish messages using the Vertx event bus.
//      *
//      * @param address
//      * @return a message
//      */
//     VertxMessage messageTo(String address);
// 
//     /**
//      *
//      * @author Martin Kouba
//      */
//     public interface VertxMessage {
// 
//         VertxMessage setDeliveryOptions(DeliveryOptions deliveryOptions);
// 
//         void send(Object message);
// 
//         void send(Object message, Handler<AsyncResult<Message<Object>>> replyHandler);
// 
//         void publish(Object message);
// 
//     }
// 
// }


// Path: examples/translator/src/main/java/org/jboss/weld/vertx/examples/translator/DataCache.java
import static org.jboss.weld.vertx.examples.translator.Addresses.CLEAR_CACHE;
import static org.jboss.weld.vertx.examples.translator.Addresses.REQUEST_DATA;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.jboss.weld.vertx.VertxConsumer;
import org.jboss.weld.vertx.VertxEvent;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2016, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.jboss.weld.vertx.examples.translator;






/**
 *
 * @author Martin Kouba
 */
@ApplicationScoped
public class DataCache {

    private static final Logger LOGGER = LoggerFactory.getLogger(DataCache.class.getName());

    private final Vertx vertx;

    private final ConcurrentMap<String, List<String>> cache;

    @Inject
    public DataCache(Vertx vertx) {
        this.cache = new ConcurrentHashMap<>();
        this.vertx = vertx;
    }

    void clear(@Observes @VertxConsumer(CLEAR_CACHE) VertxEvent event) {
        LOGGER.info("Clear dictionary cache");
        cache.clear();
    }

    /**
     *
     * @param word
     * @return a list of matching translations or <code>null</code> if no data available yet
     */
    List<String> getTranslations(String word) {
        List<String> translations = cache.get(word.toLowerCase());
        if (translations == null) {
            // No translations available - send request
            // We use synchronizer to block for 2 seconds
            final BlockingQueue<List<String>> synchronizer = new LinkedBlockingQueue<>();