1 /** 2 * Copyright (C) 2010-14 pvmanager developers. See COPYRIGHT.TXT 3 * All rights reserved. Use is subject to license terms. See LICENSE.TXT 4 */ 5 /* 6 * To change this template, choose Tools | Templates 7 * and open the template in the editor. 8 */ 9 package org.epics.pvmanager; 10 11 import java.util.ArrayList; 12 import java.util.Collection; 13 import java.util.List; 14 15 /** 16 * The type support for a datasource. This optional class is provided to help 17 * create a more flexible type support in a datasource, so that support 18 * for individual types is done through runtime configuration. It provides 19 * default implementation for matching typeAdapters from the desired cache 20 * and connection payload. 21 * 22 * @author carcassi 23 */ 24 public class DataSourceTypeSupport { 25 26 /** 27 * Given a collection of type datapters, finds the one that can store 28 * data in the cache given the channel information described in the 29 * connection payload. If there isn't a unique match, an exception 30 * is thrown. 31 * 32 * @param <C> type of connection payload 33 * @param <T> datasource specific type adapter type 34 * @param typeAdapters a collection of type adapters 35 * @param cache the cache where to store the data 36 * @param connection the connection payload 37 * @return 0 if the type was not matched 38 */ 39 protected <C, T extends DataSourceTypeAdapter<? super C,?>> T find(Collection<T> typeAdapters, ValueCache<?> cache, C connection) { 40 int matched = 0; 41 List<T> matchedConverters = new ArrayList<T>(); 42 for (T converter : typeAdapters) { 43 int match = converter.match(cache, connection); 44 if (match != 0) { 45 if (match < matched) { 46 matchedConverters.clear(); 47 } 48 matchedConverters.add(converter); 49 } 50 } 51 52 if (matchedConverters.size() != 1) { 53 throw new IllegalStateException(formatMessage(cache, connection, matched, matchedConverters)); 54 } 55 56 return matchedConverters.get(0); 57 } 58 59 /** 60 * Formats the error message in case of not unique match. This 61 * allows data sources to give more specific error messages. 62 * 63 * @param cache the cache used for the match 64 * @param connection the connection payload used for the match 65 * @param match the result of the match 66 * @param matchedConverters the matched converters; will either be 0 (no match) 67 * or more than 1 (non unique match) 68 * @return the message to be passed with the exception 69 */ 70 protected String formatMessage(ValueCache<?> cache, Object connection, int match, List<? extends DataSourceTypeAdapter<?, ?>> matchedConverters) { 71 if (matchedConverters.isEmpty()) { 72 return "DataSource misconfiguration: no match found to convert payload to type. (" 73 + cache.getType() + " - " + connection + ")"; 74 } else { 75 return "DataSource misconfiguration: multiple matches found to convert payload to type. (" 76 + cache.getType() + " - " + connection + ": " + matchedConverters + ")"; 77 } 78 } 79 }