Java tutorial
/* * 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.data.internal.xml.access; import static rabbit.data.internal.xml.DatatypeUtil.toLocalDate; import static rabbit.data.internal.xml.DatatypeUtil.toXmlDate; import rabbit.data.access.IAccessor; import rabbit.data.access.model.WorkspaceStorage; import rabbit.data.internal.xml.IDataStore; import rabbit.data.internal.xml.XmlPlugin; import rabbit.data.internal.xml.schema.events.EventGroupType; import rabbit.data.internal.xml.schema.events.EventListType; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import org.eclipse.core.runtime.IPath; import org.joda.time.LocalDate; import java.io.File; import java.util.Collection; import java.util.List; import java.util.Map; import javax.xml.datatype.XMLGregorianCalendar; /** * Abstract class provides default behaviors, this class is designed * specifically for the schema. * * @param <T> The result type. * @param <E> The XML type. * @param <S> The XML category type. */ public abstract class AbstractAccessor<T, E, S extends EventGroupType> implements IAccessor<T> { private final IDataStore store; /** * Constructor. * * @param store The data store to get the data from. * @throws NullPointerException If any arguments are null. */ protected AbstractAccessor(IDataStore store) { this.store = checkNotNull(store); } @Override public final Collection<T> getData(LocalDate start, LocalDate end) { return filter(getXmlData(checkNotNull(start, "start date is null"), checkNotNull(end, "end date is null"))); } /** * Creates a data node. * * @param cal The date of the XML type. * @param type The XML type. * @return A data node, or null if one cannot be created. * @throws Exception If a data node cannot be created. */ protected abstract T createDataNode(LocalDate cal, WorkspaceStorage ws, E type) throws Exception; /** * Gets the collection of categories from the given parameter. * * @param doc The root of a document type. * @return A collection of categories. */ protected abstract Collection<S> getCategories(EventListType doc); /** * Gets the data store. * * @return The data store. */ protected final IDataStore getDataStore() { return store; } /** * Gets a collection of types from the given category. * * @param category The category. * @return A collection of objects. */ protected abstract Collection<E> getElements(S category); /** * Filters the given data. * * @param data The raw data between the two dates of * {@link #getData(LocalDate, LocalDate)}. * @return The filtered data. */ private Collection<T> filter(Multimap<WorkspaceStorage, S> data) { List<T> result = Lists.newLinkedList(); for (Map.Entry<WorkspaceStorage, S> entry : data.entries()) { LocalDate date = toLocalDate(entry.getValue().getDate()); for (E element : getElements(entry.getValue())) { T node = null; try { node = createDataNode(date, entry.getKey(), element); } catch (Exception e) { node = null; } if (node != null) { result.add(node); } } } return result; } /** * Gets the data from the XML files. * * @param start The start date of the data to get. * @param end The end date of the data to get. * @return The data between the dates, inclusive. */ private Multimap<WorkspaceStorage, S> getXmlData(LocalDate start, LocalDate end) { XMLGregorianCalendar startDate = toXmlDate(start); XMLGregorianCalendar endDate = toXmlDate(end); XmlPlugin plugin = XmlPlugin.getDefault(); IPath[] storagePaths = plugin.getStoragePaths(); Multimap<WorkspaceStorage, S> data = LinkedListMultimap.create(storagePaths.length); Multimap<WorkspaceStorage, File> files = LinkedListMultimap.create(storagePaths.length); for (IPath storagePath : storagePaths) { List<File> fileList = getDataStore().getDataFiles(start, end, storagePath); IPath workspacePath = plugin.getWorkspacePath(storagePath); files.putAll(new WorkspaceStorage(storagePath, workspacePath), fileList); } for (Map.Entry<WorkspaceStorage, File> entry : files.entries()) { for (S list : getCategories(getDataStore().read(entry.getValue()))) { XMLGregorianCalendar date = list.getDate(); if (date == null) { continue; // Ignore invalid data. } if (startDate.compare(date) <= 0 && date.compare(endDate) <= 0) { data.put(entry.getKey(), list); } } } return data; } }