/* * Copyright 2010 The Rabbit Eclipse Plug-in Project * * 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 rabbit.ui.internal.treebuilders; import rabbit.data.access.model.IData; import rabbit.data.access.model.IKey; import rabbit.ui.internal.util.ICategory; import rabbit.ui.internal.util.ICategoryProvider; import rabbit.ui.internal.viewers.ITreePathBuilder; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayListWithCapacity; import com.google.common.collect.ImmutableMap; import org.eclipse.jface.viewers.TreePath; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import java.util.Collection; import java.util.List; import java.util.Map; /** * Internal abstract class for implementing a tree builder. This type of builder * will usually take an {@code IProvider} as input and builds a collection of * tree paths based on the categories provided by an {@link ICategoryProvider}. * @param <T> the type of data. */ public abstract class AbstractDataTreeBuilder<T extends IData> implements ITreePathBuilder { private final ICategoryProvider categoryProvider; private final Map<ICategory, IKey<? extends Object>> keys; /** * Constructor. * @param categoryProvider the category provider for providing categories. * @param keys a map categorizes each category to a key, then the keys will be * used to get the data. */ protected AbstractDataTreeBuilder( ICategoryProvider categoryProvider, Map<? extends ICategory, ? extends IKey<? extends Object>> keys) { this.categoryProvider = checkNotNull(categoryProvider, "category provider"); this.keys = ImmutableMap.copyOf(checkNotNull(keys, "keys")); } @Override public List<TreePath> build(Object input) { Collection<T> data = getData(input); if (data == null) { data = emptyList(); } List<TreePath> paths = newArrayListWithCapacity(data.size()); for (T node : data) { List<Object> segments = newArrayList(); for (ICategory category : categoryProvider.getSelected()) { segments.add(node.get(keys.get(category))); } try { // Note that new TreePath(...) will also throw an exception if one of // the segments is null: paths.addAll(transform(node, new TreePath(segments.toArray()))); } catch (Exception e) { e.printStackTrace(); } } return paths; } /** * Gets the data from the input. The return value must not be null. * @param input the input element. * @return a collection of data, may be empty but must not be null. */ protected abstract Collection<T> getData(Object input); /** * Transforms the given data and path to a new collection of tree paths. * Subclasses may override this method to return tree paths to be included in * the final collection. The default implementation simply returns the given * path. * @param data the data to build the paths for. * @param path the path that has been built with the data, note that this path * will not be included in the final collection, but the returned paths * will be. * @return a collection of paths transformed from the data and the path. * @throws Exception if any error occurs. */ protected List<TreePath> transform(T data, TreePath path) throws Exception { return asList(path); } }