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 }