/* This file is part of RouteConverter. RouteConverter 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 2 of the License, or (at your option) any later version. RouteConverter 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 RouteConverter; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Copyright (C) 2007 Christian Pesch. All Rights Reserved. */ package slash.navigation.routes.remote; import slash.navigation.routes.Category; import slash.navigation.routes.Route; import slash.navigation.routes.remote.binding.CatalogType; import slash.navigation.routes.remote.binding.CategoryType; import slash.navigation.routes.remote.binding.RouteType; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Represents a category on the server which is transferred via {@link RemoteCatalog} * and represented with GPX documents. * * @author Christian Pesch */ public class RemoteCategory implements Category { private final RemoteCatalog catalog; private final String href; private String name; private CategoryType categoryType; public RemoteCategory(RemoteCatalog catalog, String href) { this.catalog = catalog; this.href = href; } public RemoteCategory(RemoteCatalog catalog, String href, String name) { this(catalog, href); this.name = name; } RemoteCatalog getCatalog() { return catalog; } public String getHref() { return href; } private synchronized CategoryType getCategoryType() throws IOException { if (categoryType == null) { CatalogType catalogType = getCatalog().fetch(getHref()); categoryType = catalogType.getCategory(); // avoid subsequent NullPointerExceptions on server errors if (categoryType == null) categoryType = new CategoryType(); } return categoryType; } synchronized void invalidate() { categoryType = null; name = null; } private synchronized void recursiveInvalidate() { for (RemoteCategory category : getCachedSubCategories()) category.recursiveInvalidate(); invalidate(); } private List<RemoteCategory> getCachedSubCategories() { List<RemoteCategory> categories = new ArrayList<>(); if (categoryType != null) for (CategoryType subCategory : categoryType.getCategory()) { categories.add(new RemoteCategory(getCatalog(), subCategory.getHref(), subCategory.getName())); } return categories; } /*for tests*/Category getParent() throws IOException { return new RemoteCategory(getCatalog(), getCategoryType().getParent()); } public synchronized String getName() throws IOException { if (name != null) return name; return getCategoryType().getName(); } public List<Category> getCategories() throws IOException { List<Category> categories = new ArrayList<>(); for (CategoryType subCategory : getCategoryType().getCategory()) { categories.add(new RemoteCategory(getCatalog(), subCategory.getHref(), subCategory.getName())); } return categories; } public List<Route> getRoutes() throws IOException { List<Route> routes = new ArrayList<>(); for (RouteType route : getCategoryType().getRoute()) { routes.add(new RemoteRoute(this, route.getHref(), route.getDescription(), route.getCreator(), route.getUrl())); } return routes; } public Category create(String name) throws IOException { String resultUrl = getCatalog().addCategory(getHref(), name); invalidate(); return new RemoteCategory(getCatalog(), resultUrl); } public synchronized void update(Category parent, String name) throws IOException { getCatalog().updateCategory(getHref(), parent != null ? parent.getHref() : getParent().getHref(), name); this.name = name; recursiveInvalidate(); } public void delete() throws IOException { getCatalog().deleteCategory(getHref()); } public Route createRoute(String description, File localFile) throws IOException { String fileUrl = getCatalog().addFile(localFile); String routeUrl = getCatalog().addRoute(getHref(), description, fileUrl, null); invalidate(); return new RemoteRoute(this, routeUrl); } public Route createRoute(String description, String remoteUrl) throws IOException { String routeUrl = getCatalog().addRoute(getHref(), description, null, remoteUrl); invalidate(); return new RemoteRoute(this, routeUrl); } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RemoteCategory category = (RemoteCategory) o; return getCatalog().equals(category.getCatalog()) && getHref().equals(category.getHref()); } public int hashCode() { int result; result = getCatalog().hashCode(); result = 31 * result + getHref().hashCode(); return result; } public String toString() { return getClass().getSimpleName() + "[href=" + getHref() + "]"; } }