FileDocCategorySizeDatePackage
GOMUtils.javaAPI DocApache Lucene 2.1.011027Wed Feb 14 10:45:58 GMT 2007org.apache.lucene.gdata.gom.core.utils

GOMUtils.java

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.lucene.gdata.gom.core.utils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.lucene.gdata.gom.ContentType;
import org.apache.lucene.gdata.gom.GOMAttribute;
import org.apache.lucene.gdata.gom.GOMLink;
import org.apache.lucene.gdata.gom.GOMNamespace;
import org.apache.lucene.gdata.gom.core.GDataParseException;
import org.apache.lucene.gdata.gom.core.GOMAttributeImpl;

/**
 * @author Simon Willnauer
 * 
 */
public class GOMUtils {

	/*
	 * Possible values 2003-12-13T18:30:02Z 2003-12-13T18:30:02.25Z
	 * 2003-12-13T18:30:02+01:00 2003-12-13T18:30:02.25+01:00
	 */
	private static final Pattern RFC3339_DATE_PATTERN = Pattern.compile(
			"(\\d\\d\\d\\d)" + // #YEAR
					"\\-(\\d\\d)" + // #MONTH
					"\\-(\\d\\d)[Tt]" + // #DAY
					"(\\d\\d)" + // #HOURS
					":(\\d\\d)" + // #MINUTES
					":(\\d\\d)" + // #SECONDS
					"(\\.(\\d+))?" + // #MILLISorless
					"([Zz]|((\\+|\\-)(\\d\\d):(\\d\\d)))?"// #TIMEZONESHIFT
			, Pattern.COMMENTS);

	static final String ATTRIBUTE_TYPE = "type";

	static final GOMAttribute TEXT_TYPE;

	static final GOMAttribute HTML_TYPE;

	static final GOMAttribute XHTML_TYPE;

	static final GOMAttribute TEXT_TYPE_DEFAULT_NS;

	static final GOMAttribute HTML_TYPE_DEFAULT_NS;

	static final GOMAttribute XHTML_TYPE_DEFAULT_NS;

	static {
		TEXT_TYPE = new GOMAttributeImpl(GOMNamespace.ATOM_NS_URI,
				GOMNamespace.ATOM_NS_PREFIX, ATTRIBUTE_TYPE, ContentType.TEXT
						.name().toLowerCase());
		HTML_TYPE = new GOMAttributeImpl(GOMNamespace.ATOM_NS_URI,
				GOMNamespace.ATOM_NS_PREFIX, ATTRIBUTE_TYPE, ContentType.HTML
						.name().toLowerCase());
		XHTML_TYPE = new GOMAttributeImpl(GOMNamespace.ATOM_NS_URI,
				GOMNamespace.ATOM_NS_PREFIX, ATTRIBUTE_TYPE, ContentType.XHTML
						.name().toLowerCase());

		TEXT_TYPE_DEFAULT_NS = new GOMAttributeImpl(ATTRIBUTE_TYPE,
				ContentType.TEXT.name().toLowerCase());
		HTML_TYPE_DEFAULT_NS = new GOMAttributeImpl(ATTRIBUTE_TYPE,
				ContentType.HTML.name().toLowerCase());
		XHTML_TYPE_DEFAULT_NS = new GOMAttributeImpl(ATTRIBUTE_TYPE,
				ContentType.XHTML.name().toLowerCase());

	}

	/**
	 * @param type
	 * @return
	 */
	public static GOMAttribute getAttributeByContentType(ContentType type) {
		switch (type) {
		case HTML:
			return HTML_TYPE;
		case XHTML:
			return XHTML_TYPE;

		default:
			return TEXT_TYPE;
		}

	}

	/**
	 * @param type
	 * @return
	 */
	public static GOMAttribute getAttributeByContentTypeDefaultNs(
			ContentType type) {
		if (type == null)
			return TEXT_TYPE_DEFAULT_NS;
		switch (type) {
		case HTML:
			return HTML_TYPE_DEFAULT_NS;
		case XHTML:
			return XHTML_TYPE_DEFAULT_NS;

		default:
			return TEXT_TYPE_DEFAULT_NS;
		}

	}

	/**
	 * Builds a atom namespace attribute
	 * 
	 * @param aValue
	 *            attribute value
	 * @param aName
	 *            attribute name
	 * @return a GOMAttribute
	 */
	public static GOMAttribute buildAtomAttribute(String aValue, String aName) {
		return new GOMAttributeImpl(GOMNamespace.ATOM_NS_URI,
				GOMNamespace.ATOM_NS_PREFIX, aName, aValue);
	}

	/**
	 * @param aValue
	 * @param aName
	 * @return
	 */
	public static GOMAttribute buildDefaultNamespaceAttribute(String aValue,
			String aName) {
		return new GOMAttributeImpl(aName, aValue);
	}

	/**
	 * @param aValue
	 * @param aName
	 * @return
	 */
	public static GOMAttribute buildXMLNamespaceAttribute(String aValue,
			String aName) {
		return new GOMAttributeImpl(GOMNamespace.XML_NS_URI,
				GOMNamespace.XML_NS_PREFIX, aName, aValue);
	}

	/**
	 * @param aString
	 * @return
	 */
	public static boolean isRfc3339DateFormat(String aString) {
		Matcher aMatcher = RFC3339_DATE_PATTERN.matcher(aString);
		return aMatcher.matches();
	}

	/**
	 * @param aString
	 * @return
	 */
	public static long parseRfc3339DateFormat(String aString) {
		if (aString == null)
			throw new IllegalArgumentException(
					"Date-Time String must not be null");
		Matcher aMatcher = RFC3339_DATE_PATTERN.matcher(aString);

		if (!aMatcher.matches()) {
			throw new GDataParseException(
					"Invalid RFC3339 date / time pattern -- " + aString);
		}
		int grCount = aMatcher.groupCount();
		if (grCount > 13)
			throw new GDataParseException(
					"Invalid RFC3339 date / time pattern -- " + aString);

		Integer timeZoneShift = null;
		Calendar dateTime = null;
		try {

			if (aMatcher.group(9) == null) {
				// skip time zone
			} else if (aMatcher.group(9).equalsIgnoreCase("Z")) {
				timeZoneShift = new Integer(0);
			} else {
				timeZoneShift = new Integer((Integer
						.valueOf(aMatcher.group(12)) * 60 + Integer
						.valueOf(aMatcher.group(13))));
				if (aMatcher.group(11).equals("-")) {
					timeZoneShift = new Integer(-timeZoneShift.intValue());
				}
			}

			dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
			;
			dateTime.clear();
			dateTime.set(Integer.valueOf(aMatcher.group(1)), Integer
					.valueOf(aMatcher.group(2)) - 1, Integer.valueOf(aMatcher
					.group(3)), Integer.valueOf(aMatcher.group(4)), Integer
					.valueOf(aMatcher.group(5)), Integer.valueOf(aMatcher
					.group(6)));
			// seconds with milliseconds
			if (aMatcher.group(8) != null && aMatcher.group(8).length() > 0) {

				dateTime.set(Calendar.MILLISECOND, new BigDecimal("0."/*
																		 * use
																		 * big
																		 * dec
																		 * this
																		 * could
																		 * be
																		 * big!!
																		 */
						+ aMatcher.group(8)).movePointRight(3).intValue());
			}
		} catch (NumberFormatException e) {
			throw new GDataParseException(
					"Invalid RFC3339 date / time pattern -- " + aString, e);
		}

		long retVal = dateTime.getTimeInMillis();
		if (timeZoneShift != null) {
			retVal -= timeZoneShift.intValue() * 60000;
		}

		return retVal;
	}

	/**
	 * @param aMillisecondLong
	 * @return
	 */
	public static String buildRfc3339DateFormat(long aMillisecondLong) {
		Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		instance.setTimeInMillis(aMillisecondLong);

		StringBuilder builder = new StringBuilder();
		// 2003-12-13T18:30:02.25+01:00
		int time = 0;
		time = instance.get(Calendar.YEAR);
		if (time < 1000)
			builder.append("0");
		if (time < 100)
			builder.append("0");
		if (time < 10)
			builder.append("0");
		builder.append(time);
		builder.append('-');
		time = instance.get(Calendar.MONTH);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append('-');
		time = instance.get(Calendar.DAY_OF_MONTH);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append('T');
		time = instance.get(Calendar.HOUR_OF_DAY);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append(':');
		time = instance.get(Calendar.MINUTE);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append(':');
		time = instance.get(Calendar.SECOND);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append('.');
		builder.append(instance.get(Calendar.MILLISECOND));
		// this is always GMT offset -> 0
		builder.append('Z');

		return builder.toString();
	}

	/**
	 * @param aMillisecondLong
	 * @return
	 */
	public static String buildRfc822Date(long aMillisecondLong) {
		/*
		 * Rather implement it for a special case as use SDF. SDF is very
		 * expensive to create and not thread safe so it should be synchronized
		 * of pooled
		 */
		Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		instance.setTimeInMillis(aMillisecondLong);

		StringBuilder builder = new StringBuilder();
		// Sun, 06 Aug 2006 00:53:49 +0000
		// EEE, dd MMM yyyy HH:mm:ss Z

		switch (instance.get(Calendar.DAY_OF_WEEK)) {
		case Calendar.SUNDAY:
			builder.append("Sun");
			break;
		case Calendar.MONDAY:
			builder.append("Mon");
			break;
		case Calendar.TUESDAY:
			builder.append("Tue");
			break;
		case Calendar.WEDNESDAY:
			builder.append("Wed");
			break;
		case Calendar.THURSDAY:
			builder.append("Thu");
			break;
		case Calendar.FRIDAY:
			builder.append("Fri");
			break;
		case Calendar.SATURDAY:
			builder.append("Sat");
			break;
		default:
			break;
		}
		builder.append(',');
		builder.append(' ');

		int time = 0;
		time = instance.get(Calendar.DAY_OF_MONTH);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append(' ');
		switch (instance.get(Calendar.MONTH)) {
		case Calendar.JANUARY:
			builder.append("Jan");
			break;
		case Calendar.FEBRUARY:
			builder.append("Feb");
			break;
		case Calendar.MARCH:
			builder.append("Mar");
			break;
		case Calendar.APRIL:
			builder.append("Apr");
			break;
		case Calendar.MAY:
			builder.append("May");
			break;
		case Calendar.JUNE:
			builder.append("Jun");
			break;
		case Calendar.JULY:
			builder.append("Jul");
			break;
		case Calendar.AUGUST:
			builder.append("Aug");
			break;
		case Calendar.SEPTEMBER:
			builder.append("Sep");
			break;
		case Calendar.OCTOBER:
			builder.append("Oct");
			break;
		case Calendar.NOVEMBER:
			builder.append("Nov");
			break;
		case Calendar.DECEMBER:
			builder.append("Dec");
			break;

		default:
			break;
		}
		builder.append(' ');
		time = instance.get(Calendar.YEAR);
		if (time < 1000)
			builder.append("0");
		if (time < 100)
			builder.append("0");
		if (time < 10)
			builder.append("0");
		builder.append(time);
		builder.append(' ');

		time = instance.get(Calendar.HOUR_OF_DAY);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append(':');
		time = instance.get(Calendar.MINUTE);
		if (time < 10)
			builder.append(0);
		builder.append(time);
		builder.append(':');
		time = instance.get(Calendar.SECOND);
		if (time < 10)
			builder.append(0);
		builder.append(time);

		// this is always GMT offset -> 0
		builder.append(" +0000");
		return builder.toString();
	}

	public GOMLink getHtmlLink(List<GOMLink> links) {
		for (GOMLink link : links) {
			if ((link.getRel() == null || link.getRel().equals("alternate"))
					&& (link.getType() == null || link.getType()
							.equalsIgnoreCase("html")))
				return link;
		}
		return null;
	}
}