/* * #%L * gitools-core * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package org.gitools.matrix.model.matrix.element; import org.gitools.api.matrix.ILayerAdapter; import org.gitools.api.matrix.IMatrix; import org.gitools.api.matrix.IMatrixPosition; import org.gitools.matrix.model.MatrixLayer; import org.gitools.matrix.model.MatrixLayers; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; public class LayerAdapter<T> implements ILayerAdapter<T> { private Class<? extends T> elementClass; private MatrixLayers<BeanMatrixLayer> matrixLayers; public LayerAdapter(Class<? extends T> elementClass) { super(); this.elementClass = elementClass; createLayers(); } public Class<? extends T> getElementClass() { return elementClass; } @Override public MatrixLayers<BeanMatrixLayer> getMatrixLayers() { return matrixLayers; } @Override public <T> BeanMatrixLayer<T> getLayer(Class<T> layerClass, String layerName) { return (BeanMatrixLayer<T>) getMatrixLayers().get(layerName); } @Override public void set(IMatrix matrix, T value, IMatrixPosition position) { set(matrix, value, position.toVector()); } @Override public void set(IMatrix matrix, T value, String... identifiers) { if (value == null) { return; } try { for (BeanMatrixLayer layer : matrixLayers) { Method getter = layer.getGetterMethod(); matrix.set(layer, getter.invoke(value), identifiers); } } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } @Override public T get(IMatrix matrix, IMatrixPosition position) { return get(matrix, position.toVector()); } @Override public T get(IMatrix matrix, String... identifiers) { T value = null; try { value = getElementClass().newInstance(); for (BeanMatrixLayer layer : matrixLayers) { Method setter = layer.getSetterMethod(); Object result = matrix.get(layer, identifiers); if (result != null) { setter.invoke(value, result); } } } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } return value; } private void createLayers() { List<BeanMatrixLayer> layers = new ArrayList<>(); final HashMap<String, Integer> groupCount = new HashMap<>(); for (Method m : getElementClass().getMethods()) { boolean isGet = m.getName().startsWith("get"); if (m.getParameterTypes().length == 0 && !m.getName().equals("getClass") && (isGet || m.getName().startsWith("is"))) { final String getterName = isGet ? m.getName().substring(3) : m.getName().substring(2); final Class<?> propertyClass = m.getReturnType(); String id = getterName; String name = id; String description = ""; HashSet<String> groups = new HashSet(); LayerDef a = m.getAnnotation(LayerDef.class); if (a != null) { if (a.id() != null) { id = a.id(); } if (a.name() != null) { name = a.name(); } if (a.description() != null) { description = a.description(); } if (a.groups() != null) { for (String group : a.groups()) { groupCount.put(group, groupCount.get(group) == null ? 1 : groupCount.get(group)+1); groups.add(group); } } } Method setterMethod = null; try { setterMethod = getElementClass().getMethod("set" + getterName, new Class<?>[]{propertyClass}); } catch (Exception e) { } BeanMatrixLayer prop = new BeanMatrixLayer(id, name, description, propertyClass, groups, m, setterMethod); layers.add(prop); } } Collections.sort(layers, new Comparator<MatrixLayer>() { @Override public int compare(MatrixLayer o1, MatrixLayer o2) { String g1 = smallestGroup(o1, groupCount); String g2 = smallestGroup(o2, groupCount); // order by smallest group Size; if (groupCount.get(g1) < groupCount.get(g2)) { return -1; } else if (groupCount.get(g1) > groupCount.get(g2)) { return 1; } // if equal, order by group Name int comp = g1.compareTo(g2); if (comp != 0) { return comp; } else { // if equal compare by layer name; return o1.getName().compareTo(o2.getName()); } } private String smallestGroup(MatrixLayer layer, HashMap<String, Integer> groupCount) { int min = -1; String name = ""; Iterator iterator = layer.getGroups().iterator(); while (iterator.hasNext()) { String group = (String) iterator.next(); int size = groupCount.get(group); if (size < min || min < 0) { min = size; name = group; } } return name; } }); this.matrixLayers = new MatrixLayers<>(layers); } }