/* Copyright (c) 2008 Google Inc.
*
* 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 com.google.gdata.data.geo.impl;
import com.google.gdata.data.Extension;
import com.google.gdata.data.ExtensionPoint;
import com.google.gdata.data.ExtensionProfile;
import com.google.gdata.data.geo.Box;
import com.google.gdata.data.geo.BoxData;
import com.google.gdata.data.geo.Point;
/**
* Implementation of the BoxData interface. Currently only supports a
* non-repeating Box extension. This class uses an {@link ExtensionPoint} that
* is passed in to store the Box extension.
*
*
*/
public class BoxDataImpl implements BoxData {
private final ExtensionPoint extPoint;
/**
* Construct a new BoxData with the given extension point as the backing
* storage of the data.
*/
public BoxDataImpl(ExtensionPoint extensionPoint) {
this.extPoint = extensionPoint;
}
/**
* If there is an existing box this will set the new values on it.
* Otherwise it will create a new GeoRssWhere element to contain them.
* If just one argument is null it will throw an exception.
*/
public void setGeoBoundingBox(Point lowerLeft, Point upperRight) {
setGeoBoundingBox(new GeoRssWhere(lowerLeft, upperRight));
}
/**
* Sets the geo bounding box to the given box. If there is an existing box
* it will copy the values from the given box, otherwise it will use the new
* box as the extension.
*/
public void setGeoBoundingBox(Box box) {
setBox(extPoint, box);
}
/**
* Gets the geo bounding box for this extension point.
*/
public Box getGeoBoundingBox() {
return getBox(extPoint);
}
public void clearGeoBoundingBox() {
clearBox(extPoint);
}
/**
* Sets the geo bounding box of the extension passed in. This will first
* try to replace any existing bounding box information. If there is no
* existing bounding box, then it'll simply add the box extension.
*
* @param ext The extension point to add the Box to.
* @param box The new box information.
*/
public static void setBox(ExtensionPoint ext, Box box) {
Box existing = getBoxExtension(ext);
if (existing != null) {
Point lowerLeft = box != null ? box.getLowerLeft() : null;
Point upperRight = box != null ? box.getUpperRight() : null;
// If we have a box already, we copy the new points onto it if we can.
existing.setGeoLocation(lowerLeft, upperRight);
} else if (box != null) {
// We don't have a box yet, so we set it directly here. We actually use
// the passed-in extension in this case.
ext.setExtension(box);
}
}
/**
* Helper method to retrieve the Box extension point. Note this will
* return empty boxes but will only return an GeoRssWhere extension point
* if it contains a GmlEnvelope.
*
* @param ext The containing extension point.
* @return An extension point that implements the Box interface and contain
* box information.
*/
public static Box getBox(ExtensionPoint ext) {
Box b = getBoxExtension(ext);
if (b != null) {
if (b instanceof GeoRssWhere) {
GeoRssWhere geoWhere = (GeoRssWhere)b;
if (geoWhere.hasBox()) {
return geoWhere;
}
} else {
return b;
}
}
return null;
}
/**
* Iterates through all the extension points and finds the first matching
* Box extension (any box extension).
*
* NOTE(pingc): Package private for testing. DO NOT USE.
*
* @param ext The extension point to search through.
* @return A box extension point. This includes GeoRssWhere that may only
* contain a point.
*/
static Box getBoxExtension(ExtensionPoint ext) {
for (Extension e : ext.getExtensions()) {
if (e instanceof Box) {
return (Box) e;
}
}
return null;
}
/**
* Removes the first Box extension found on the extension point. If the
* box extension is a GeoRssWhere, it will only remove the GeoRssWhere
* extension if it does not contain a Point extension.
*
* @param ext The extension point from which to clear the Box extension.
*/
public static void clearBox(ExtensionPoint ext) {
Box b = getBoxExtension(ext);
if (b != null) {
if (b instanceof GeoRssWhere) {
GeoRssWhere where = (GeoRssWhere)b;
if (where.hasPoint()) {
// If the GeoRssWhere has a point, just clear the box. Otherwise
// remove the whole thing.
where.clearBox();
return;
}
}
ext.removeExtension(b);
}
}
/*
* Declare the extensions that are used for storing Box information.
*/
public void declareExtensions(ExtensionProfile extProfile) {
Class<? extends ExtensionPoint> extClass = extPoint.getClass();
// Declare all all Box implementations here so they are parsable
// in the context of extClass.
extProfile.declare(extClass, GeoRssBox.getDefaultDescription(false));
extProfile.declare(extClass, GeoRssWhere.getDefaultDescription(false));
new GeoRssWhere().declareExtensions(extProfile);
// Also declare GmlEnvelope as an allowed box, even though it should
// be embedded in a georss:where. This is just to be more forgiving
// to clients of our apis.
extProfile.declare(extClass, GmlEnvelope.getDefaultDescription(false));
new GmlEnvelope().declareExtensions(extProfile);
}
}