001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.widget.google.provider;
023:
024: import org.jboss.portal.common.net.URLTools;
025: import org.jboss.portal.common.io.IOTools;
026: import org.jboss.portal.widget.WidgetQuery;
027: import org.jboss.portal.widget.exceptions.WidgetException;
028: import org.jboss.portal.widget.google.directory.GGWidgetDirectoryFactory;
029: import org.jboss.portal.widget.google.metadata.GGWidgetMetaData;
030: import org.jboss.xb.binding.JBossXBException;
031: import org.jboss.xb.binding.Unmarshaller;
032: import org.jboss.xb.binding.UnmarshallerFactory;
033: import org.jboss.xb.binding.ObjectModelFactory;
034:
035: import java.net.URL;
036: import java.net.MalformedURLException;
037: import java.net.SocketTimeoutException;
038: import java.text.NumberFormat;
039: import java.util.ArrayList;
040: import java.util.Iterator;
041: import java.util.List;
042: import java.io.ByteArrayInputStream;
043: import java.io.IOException;
044: import java.io.InputStream;
045:
046: /**
047: * @todo make the timeouts parameterizable
048: *
049: * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
050: * @author <a href="mailto:boleslaw dot dawidowicz at jboss dot com">Boleslaw Dawidowicz</a>
051: * @version $Revision: 9227 $
052: */
053: public class GGQueryResultBuilder {
054:
055: private static final org.jboss.logging.Logger log = org.jboss.logging.Logger
056: .getLogger(GGQueryResultBuilder.class);
057:
058: /** . */
059: public static final String GHAPI_URI = "http://www.google.com/apis/homepage";
060:
061: /** . */
062: private final URL url;
063:
064: public GGQueryResultBuilder(WidgetQuery query)
065: throws MalformedURLException {
066: if (query == null) {
067: throw new IllegalArgumentException();
068: }
069: this .url = query.buildQueryURL();
070: }
071:
072: public GGQueryResultBuilder(URL url) {
073: if (url == null) {
074: throw new IllegalArgumentException();
075: }
076: this .url = url;
077: }
078:
079: public GGQueryResult build(int connectionTimeout)
080: throws WidgetException {
081: try {
082: // Read fully the URL content first
083: long millis = System.currentTimeMillis();
084: byte[] bytes;
085: if ("http".equals(url.getProtocol())) {
086: bytes = URLTools.getContent(url, connectionTimeout,
087: connectionTimeout);
088: } else {
089: InputStream in = url.openStream();
090: try {
091: bytes = IOTools.getBytes(in);
092: } finally {
093: IOTools.safeClose(in);
094: }
095: }
096:
097: //
098: if (bytes == null) {
099: throw new WidgetException(
100: "Cannot retrieve url: "
101: + url
102: + " - you can try to increase the connectionTimeout");
103: }
104:
105: String string = new String(bytes);
106: List data = null;
107:
108: Unmarshaller unmarshaller = UnmarshallerFactory
109: .newInstance().newUnmarshaller();
110: // create an instance of ObjectModelFactory
111: ObjectModelFactory factory = new GGWidgetDirectoryFactory();
112:
113: // Populate the List with data from XML
114: try {
115: data = (List) unmarshaller.unmarshal(
116: new ByteArrayInputStream(string
117: .getBytes("UTF-8")), factory, null);
118: } catch (JBossXBException e) {
119: /**
120: * Remove this block when google rss feed returns correct xml
121: */
122: // Replace incorrect characters and try the parsing a 2nd time - if it fails again we finally give up
123: String string2 = string.replace("& ", "& ");
124: unmarshaller = UnmarshallerFactory.newInstance()
125: .newUnmarshaller();
126: data = (List) unmarshaller.unmarshal(
127: new ByteArrayInputStream(string2
128: .getBytes("UTF-8")), factory, null);
129: }
130:
131: List entries = new ArrayList();
132:
133: for (Iterator iterator = data.iterator(); iterator
134: .hasNext();) {
135: GGWidgetMetaData md = (GGWidgetMetaData) iterator
136: .next();
137: GGQueryResultEntry entry = new GGQueryResultEntry(md);
138: entries.add(entry);
139: }
140: if (log.isDebugEnabled()) {
141: log
142: .debug("Fetchting directory took: "
143: + NumberFormat
144: .getInstance()
145: .format(
146: (System
147: .currentTimeMillis() - millis) / 1000.0));
148: }
149:
150: //
151: return new GGQueryResult(entries);
152: } catch (SocketTimeoutException e) {
153: throw new WidgetException(
154: "Netvibes directory query failed due to timeout. Try to increase connectionTimeout initial parameter; ",
155: e);
156: } catch (JBossXBException e) {
157: throw new WidgetException(
158: "Failed to parse directory response.", e.getCause());
159: } catch (IOException e) {
160: throw new WidgetException(
161: "Failed to perform directory lookup.", e);
162: }
163: }
164: }
|