/* Copyright (c) 2006 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.api.gbase.client;
import com.google.gdata.data.ExtensionProfile;
import com.google.gdata.data.ExtensionDescription;
import com.google.gdata.data.Extension;
import com.google.gdata.data.AttributeHelper;
import com.google.gdata.util.ParseException;
import com.google.gdata.util.XmlParser;
import com.google.gdata.util.common.xml.XmlWriter;
import org.xml.sax.Attributes;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
/**
* Object representation for the tag gm:stats.
*/
@ExtensionDescription.Default(
nsAlias = GoogleBaseNamespaces.GM_ALIAS,
nsUri = GoogleBaseNamespaces.GM_URI,
localName = "stats")
public class Stats implements Extension {
private final Statistics impressions = new Statistics();
private final Statistics clicks = new Statistics();
private final Statistics pageViews = new Statistics();
/** Gets impression count. */
public Statistics getImpressions() {
return impressions;
}
/** Gets click count. */
public Statistics getClicks() {
return clicks;
}
/** Gets page view count. */
public Statistics getPageViews() {
return pageViews;
}
public void generate(XmlWriter w, ExtensionProfile extProfile)
throws IOException {
if (impressions.getTotal() == 0 && clicks.getTotal() == 0
&& pageViews.getTotal() == 0) {
// Nothing to generate
return;
}
w.startElement(GoogleBaseNamespaces.GM, "stats", null, null);
impressions.generate(w, "impressions");
clicks.generate(w, "clicks");
pageViews.generate(w, "page_views");
w.endElement();
}
public XmlParser.ElementHandler getHandler(ExtensionProfile extProfile,
String namespace, String localName, Attributes attrs)
throws ParseException, IOException {
impressions.clear();
pageViews.clear();
clicks.clear();
return new XmlParser.ElementHandler() {
@Override
public XmlParser.ElementHandler getChildHandler(String namespace,
String localName, Attributes attrs) throws ParseException,
IOException {
if (localName.equals("impressions")) {
return new StatsSubElementHandler(impressions, attrs);
}
if (localName.equals("page_views")) {
return new StatsSubElementHandler(pageViews, attrs);
}
if (localName.equals("clicks")) {
return new StatsSubElementHandler(clicks, attrs);
}
return super.getChildHandler(namespace, localName, attrs);
}
};
}
/**
* Information about one specific use (impressions, clicks, page views).
*/
public static class Statistics {
private int total;
private Map<String, Integer> countBySource;
/**
* Puts the instance back to its initial state.
*/
void clear() {
total = 0;
countBySource = null;
}
/**
* Gets the total for this statistic.
*
* @return total
*/
public int getTotal() {
return total;
}
/**
* Sets the total for this statistic.
*
* @param total
*/
public void setTotal(int total) {
this.total = total;
}
/**
* Gets a set of sources for which a sub-total
* is available.
*
* @return set of sources
*/
public Set<String> getSources() {
if (countBySource == null) {
return Collections.emptySet();
}
return countBySource.keySet();
}
/**
* Get a sub-total for a specific source.
*
* @param source source name
* @return sub-total or -1 if it is not known
*/
public int getCountBySource(String source) {
if (countBySource == null) {
return -1;
}
Integer value = countBySource.get(source);
if (value == null) {
return -1;
}
return value;
}
/**
* Sets the sub-total for a specific source.
*
* @param source source name
* @param count sub-total or -1 if it is not known
*/
public void setCountBySource(String source, int count) {
if (count == -1) {
if (countBySource != null) {
countBySource.remove(source);
}
} else {
if (countBySource == null) {
countBySource = new HashMap<String, Integer>();
}
countBySource.put(source, count);
}
}
/** Generates the XML representation for this object. */
private void generate(XmlWriter w, String name) throws IOException {
if (total == 0) {
// Nothing to generate
return;
}
w.startElement(GoogleBaseNamespaces.GM, name,
Collections.singletonList(
new XmlWriter.Attribute("total", Integer.toString(total))), null);
if (countBySource != null && !countBySource.isEmpty()) {
w.startRepeatingElement();
for (Map.Entry<String, Integer> entry : countBySource.entrySet()) {
List<XmlWriter.Attribute> attrs =
new ArrayList<XmlWriter.Attribute>(2);
attrs.add(new XmlWriter.Attribute("name", entry.getKey()));
attrs.add(
new XmlWriter.Attribute("count", entry.getValue().toString()));
w.simpleElement(GoogleBaseNamespaces.GM, "source", attrs, null);
}
w.endRepeatingElement();
}
w.endElement();
}
}
/** Parses a sub-element of gm:stats. */
private static class StatsSubElementHandler
extends XmlParser.ElementHandler {
private final Stats.Statistics stat;
public StatsSubElementHandler(Stats.Statistics stat, Attributes attrs)
throws ParseException {
this.stat = stat;
AttributeHelper helper = new AttributeHelper(attrs);
stat.setTotal(helper.consumeInteger("total", false, 0));
helper.assertAllConsumed();
}
@Override
public XmlParser.ElementHandler getChildHandler(String namespace,
String localName, Attributes attrs)
throws ParseException, IOException {
if (GoogleBaseNamespaces.GM_URI.equals(namespace)
&& "source".equals(localName)) {
AttributeHelper helper = new AttributeHelper(attrs);
stat.setCountBySource(helper.consume("name", true),
helper.consumeInteger("count", true));
helper.assertAllConsumed();
}
return new XmlParser.ElementHandler();
}
}
}