You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Santiago Gala <sa...@gmail.com> on 2008/04/04 01:35:17 UTC
Re: svn commit: r644123 [1/3] - in /incubator/shindig/trunk:
features/core.io/ java/gadgets/ java/gadgets/conf/
java/gadgets/src/main/java/org/apache/shindig/gadgets/
java/gadgets/src/main/java/org/apache/shindig/gadgets/http/
java/gadgets/src/main/j
El jue, 03-04-2008 a las 11:46 -0700, Kevin Brown escribió:
> Those files should have been removed entirely (the code was moved or is
> simply unnecessary). I clearly don't understand SVN well enough yet to be
> using it!
I committed the removal, not every day I can get the credit of
contributing 0 lines of java code in 8 different files. :)
Regards
Santiago
>
> On Thu, Apr 3, 2008 at 11:23 AM, Santiago Gala <sa...@gmail.com>
> wrote:
>
> > quite possibly a small oversight after applying the patch, but
> >
> > $ find . -name .svn -prune -or -type f -empty -print
> >
> > ./java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRendererTest.java
> >
> > ./java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcRequestTest.java
> >
> > ./java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsonRpcGadgetJob.java
> >
> > ./java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsonRpcRequest.java
> >
> > ./java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfig.java
> >
> > ./java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfigReader.java
> >
> > :) (I am not sure it is not a working copy problem here)
> >
> > Regards
> > Santiago
> >
> >
> > El jue, 03-04-2008 a las 00:40 +0000, etnu@apache.org escribió:
> > > Author: etnu
> > > Date: Wed Apr 2 17:40:05 2008
> > > New Revision: 644123
> > >
> > > URL: http://svn.apache.org/viewvc?rev=644123&view=rev
> > > Log:
> > > Wiring up Guice support as discussed in SHINDIG-152.
> > >
> > > This is a very significant change for anyone who has maintained
> > customized implementations of any of the core Shindig classes, but it
> > greatly simplifies the task of extending te server.
> > >
> > > This patch also incorporates Brian Eaton's signing interface
> > improvements discussed in SHINDIG-157.
> > >
> > >
> > > Added:
> > > incubator/shindig/trunk/java/gadgets/conf/
> > > incubator/shindig/trunk/java/gadgets/conf/gadgets.properties
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetTokenDecoder.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/CachedContentFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetTokenDecoder.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloadFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcherFactory.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingTask.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GuiceServletContextListener.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/HttpGuiceModule.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/InjectedServlet.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsonRpcHandler.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxiedContentFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/UrlGenerator.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/InterceptingContentFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRenderingTaskTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpTestFixture.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcHandlerTest.java
> > > Removed:
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetSigner.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DataFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSigner.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/NullRequestSigner.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RequestSigner.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SignedFetchRequestSigner.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/CrossServletState.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/DefaultCrossServletState.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SignedFetchRequestSignerTest.java
> > > Modified:
> > > incubator/shindig/trunk/features/core.io/io.js
> > > incubator/shindig/trunk/java/gadgets/pom.xml
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetBlacklist.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetToken.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicRemoteContentFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfig.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfigReader.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetToken.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentRequest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SyndicatorConfig.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderer.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/GadgetRenderingServlet.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsServlet.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsonRpcGadgetContext.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsonRpcGadgetJob.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/JsonRpcRequest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyServlet.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/RpcServlet.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/GadgetDataServlet.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/opensocial/OpenSocialDataHandler.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/BlobCrypter.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/ResourceLoader.java
> > > incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetServerTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsLibraryTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRendererTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcRequestTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java
> > >
> > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/util/BlobCrypterTest.java
> > >
> > > Modified: incubator/shindig/trunk/features/core.io/io.js
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/features/core.io/io.js?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > --- incubator/shindig/trunk/features/core.io/io.js (original)
> > > +++ incubator/shindig/trunk/features/core.io/io.js Wed Apr 2 17:40:05
> > 2008
> > > @@ -193,10 +193,10 @@
> > > * false otherwise
> > > */
> > > function respondWithPreload(postData, params, callback) {
> > > - if (gadgets.io.preloaded && gadgets.io.preloaded[postData.url]) {
> > > - var preload = gadgets.io.preloaded[postData.url];
> > > + if (gadgets.io.preloaded_ && gadgets.io.preloaded_[postData.url]) {
> > > + var preload = gadgets.io.preloaded_[postData.url];
> > > if (postData.httpMethod == "GET" && postData.authz == "none") {
> > > - delete gadgets.io.preloaded[postData.url];
> > > + delete gadgets.io.preloaded_[postData.url];
> > > if (preload.rc !== 200) {
> > > callback({errors : ["Error " + preload.rc]});
> > > } else {
> > > @@ -349,4 +349,4 @@
> > >
> > > gadgets.io.AuthorizationType = gadgets.util.makeEnum([
> > > "NONE", "SIGNED", "AUTHENTICATED"
> > > -]);
> > > \ No newline at end of file
> > > +]);
> > >
> > > Added: incubator/shindig/trunk/java/gadgets/conf/gadgets.properties
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/conf/gadgets.properties?rev=644123&view=auto
> > >
> > ==============================================================================
> > > --- incubator/shindig/trunk/java/gadgets/conf/gadgets.properties (added)
> > > +++ incubator/shindig/trunk/java/gadgets/conf/gadgets.properties Wed Apr
> > 2 17:40:05 2008
> > > @@ -0,0 +1,9 @@
> > > +features.default=res://features/features.txt
> > > +syndicators.default=res://syndicators/default/syndicator.js
> > > +blacklist.file=
> > > +urls.iframe.prefix=/gadgets/ifr?
> > > +urls.js.prefix=/gadgets/js/
> > > +signing.key-name=
> > > +signing.key-file=
> > > +
> > > +
> > >
> > > Modified: incubator/shindig/trunk/java/gadgets/pom.xml
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.xml?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > --- incubator/shindig/trunk/java/gadgets/pom.xml (original)
> > > +++ incubator/shindig/trunk/java/gadgets/pom.xml Wed Apr 2 17:40:05
> > 2008
> > > @@ -153,13 +153,6 @@
> > > <directory>../../features</directory>
> > > </resource>
> > > <resource>
> > > - <targetPath>syndicators/default</targetPath>
> > > - <directory>../../config</directory>
> > > - <includes>
> > > - <include>syndicator.js</include>
> > > - </includes>
> > > - </resource>
> > > - <resource>
> > > <!-- duplicated here for the jar build. -->
> > > <!-- TODO: Eliminate duplicate copies in WAR output -->
> > > <!-- this is relative to the pom.xml directory -->
> > > @@ -169,6 +162,16 @@
> > > <include>**/*.*</include>
> > > </includes>
> > > </resource>
> > > + <resource>
> > > + <targetPath>syndicators/default</targetPath>
> > > + <directory>../../config</directory>
> > > + <includes>
> > > + <include>syndicator.js</include>
> > > + </includes>
> > > + </resource>
> > > + <resource>
> > > + <directory>conf</directory>
> > > + </resource>
> > > </resources>
> > > </build>
> > > <repositories>
> > > @@ -229,7 +232,12 @@
> > > <version>20080229</version>
> > > <scope>compile</scope>
> > > </dependency>
> > > - <dependency>
> > > + <dependency>
> > > + <groupId>com.google.code.guice</groupId>
> > > + <artifactId>guice</artifactId>
> > > + <version>1.0</version>
> > > + </dependency>
> > > + <dependency>
> > > <groupId>commons-lang</groupId>
> > > <artifactId>commons-lang</artifactId>
> > > <version>2.3</version>
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetBlacklist.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetBlacklist.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetBlacklist.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetBlacklist.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -17,6 +17,9 @@
> > > */
> > > package org.apache.shindig.gadgets;
> > >
> > > +import com.google.inject.Inject;
> > > +import com.google.inject.name.Named;
> > > +
> > > import java.io.BufferedReader;
> > > import java.io.File;
> > > import java.io.FileReader;
> > > @@ -71,7 +74,15 @@
> > > public BasicGadgetBlacklist(File blacklistFile) throws IOException {
> > > exactMatches = new HashSet<String>();
> > > regexpMatches = new ArrayList<Pattern>();
> > > - parseBlacklist(blacklistFile);
> > > + if (blacklistFile.exists()) {
> > > + parseBlacklist(blacklistFile);
> > > + }
> > > + }
> > > +
> > > + @Inject
> > > + public BasicGadgetBlacklist(@Named("blacklist.file") String file)
> > > + throws IOException {
> > > + this(new File(file));
> > > }
> > >
> > > private void parseBlacklist(File blacklistFile) throws IOException {
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetToken.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetToken.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetToken.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetToken.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -27,24 +27,24 @@
> > > /**
> > > * Primitive token implementation that uses stings as tokens.
> > > */
> > > -class BasicGadgetToken implements GadgetToken {
> > > +public class BasicGadgetToken implements GadgetToken {
> > > /** serialized form of the token */
> > > private final String token;
> > > -
> > > +
> > > /** data from the token */
> > > private final Map<String, String> tokenData;
> > > -
> > > +
> > > /** tool to use for signing and encrypting the token */
> > > private BlobCrypter crypter = new BlobCrypter(INSECURE_KEY);
> > > -
> > > +
> > > private static final byte[] INSECURE_KEY =
> > > { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
> > > -
> > > +
> > > private static final String OWNER_KEY = "o";
> > > private static final String APP_KEY = "a";
> > > private static final String VIEWER_KEY = "v";
> > > private static final String DOMAIN_KEY = "d";
> > > -
> > > +
> > > /**
> > > * {@inheritDoc}
> > > */
> > > @@ -56,14 +56,14 @@
> > > * Generates a token from an input string
> > > * @param token String form of token
> > > * @param maxAge max age of the token (in seconds)
> > > - * @throws BlobCrypterException
> > > + * @throws BlobCrypterException
> > > */
> > > public BasicGadgetToken(String token, int maxAge)
> > > - throws BlobCrypterException {
> > > + throws BlobCrypterException {
> > > this.token = token;
> > > this.tokenData = crypter.unwrap(token, maxAge);
> > > }
> > > -
> > > +
> > > public BasicGadgetToken(String owner, String viewer, String app,
> > > String domain) throws BlobCrypterException {
> > > tokenData = new HashMap<String, String>(5,1);
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetTokenDecoder.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetTokenDecoder.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetTokenDecoder.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetTokenDecoder.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,48 @@
> > > +/*
> > > + * 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.shindig.gadgets;
> > > +
> > > +import org.apache.shindig.util.BlobCrypterException;
> > > +
> > > +/**
> > > + * A GadgetTokenDecoder implementation that just provides dummy data to
> > satisfy
> > > + * tests and API calls. Do not use this for any security applications.
> > > + */
> > > +public class BasicGadgetTokenDecoder implements GadgetTokenDecoder {
> > > +
> > > + /**
> > > + * {@inheritDoc}
> > > + *
> > > + * Returns a token with some faked out values.
> > > + */
> > > + public GadgetToken createToken(String stringToken) throws
> > GadgetException {
> > > + try {
> > > + String[] tokens = stringToken.split(":");
> > > + return new BasicGadgetToken(tokens[0], tokens[1], tokens[2],
> > tokens[3]);
> > > + } catch (BlobCrypterException e) {
> > > + throw new
> > GadgetException(GadgetException.Code.INVALID_GADGET_TOKEN, e);
> > > + }
> > > + }
> > > +
> > > + /**
> > > + * Creates a signer with 24 hour token expiry
> > > + */
> > > + public BasicGadgetTokenDecoder() {
> > > + }
> > > +}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicRemoteContentFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicRemoteContentFetcher.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicRemoteContentFetcher.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicRemoteContentFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -19,19 +19,28 @@
> > >
> > > import org.apache.shindig.util.InputStreamConsumer;
> > >
> > > +import com.google.inject.Singleton;
> > > +
> > > import java.io.FileNotFoundException;
> > > import java.io.IOException;
> > > +import java.io.InputStream;
> > > import java.net.HttpURLConnection;
> > > import java.net.URLConnection;
> > > import java.util.List;
> > > import java.util.Map;
> > > +import java.util.zip.GZIPInputStream;
> > > +import java.util.zip.Inflater;
> > > +import java.util.zip.InflaterInputStream;
> > >
> > > /**
> > > * Implementation of a {@code RemoteObjectFetcher} using standard
> > java.net
> > > - * classes.
> > > + * classes. Only one instance of this should be present at any time, so
> > we
> > > + * annotate it as a Singleton to resolve Guice injection limitations.
> > > */
> > > -public class BasicRemoteContentFetcher implements RemoteContentFetcher
> > {
> > > +@Singleton
> > > +public class BasicRemoteContentFetcher extends RemoteContentFetcher {
> > > private static final int CONNECT_TIMEOUT_MS = 5000;
> > > + private static final int DEFAULT_MAX_OBJECT_SIZE = 1024 * 1024;
> > >
> > > private final int maxObjSize;
> > >
> > > @@ -41,10 +50,18 @@
> > > * @param maxObjSize Maximum size, in bytes, of object to fetch
> > > */
> > > public BasicRemoteContentFetcher(int maxObjSize) {
> > > + super(null);
> > > this.maxObjSize = maxObjSize;
> > > }
> > >
> > > /**
> > > + * Creates a new fetcher using the default maximum object size.
> > > + */
> > > + public BasicRemoteContentFetcher() {
> > > + this(DEFAULT_MAX_OBJECT_SIZE);
> > > + }
> > > +
> > > + /**
> > > * Initializes the connection.
> > > *
> > > * @param request
> > > @@ -56,6 +73,7 @@
> > > URLConnection fetcher;
> > > fetcher = request.getUri().toURL().openConnection();
> > > fetcher.setConnectTimeout(CONNECT_TIMEOUT_MS);
> > > + fetcher.setRequestProperty("Accept-Encoding", "gzip, deflate");
> > > if (fetcher instanceof HttpURLConnection) {
> > > ((HttpURLConnection)fetcher).setInstanceFollowRedirects(true);
> > > Map<String, List<String>> reqHeaders = request.getAllHeaders();
> > > @@ -96,12 +114,25 @@
> > > } else {
> > > responseCode = RemoteContent.SC_OK;
> > > }
> > > - byte[] body = InputStreamConsumer.readToByteArray(
> > > - fetcher.getInputStream(), maxObjSize);
> > > +
> > > + String encoding = fetcher.getContentEncoding();
> > > + InputStream is = null;
> > > + // Create the appropriate stream wrapper based on the encoding
> > type.
> > > + if (encoding == null) {
> > > + is = fetcher.getInputStream();
> > > + } else if (encoding.equalsIgnoreCase("gzip")) {
> > > + is = new GZIPInputStream(fetcher.getInputStream());
> > > + } else if (encoding.equalsIgnoreCase("deflate")) {
> > > + Inflater inflater = new Inflater(true);
> > > + is = new InflaterInputStream(fetcher.getInputStream(), inflater);
> > > + }
> > > +
> > > + byte[] body = InputStreamConsumer.readToByteArray(is, maxObjSize);
> > > return new RemoteContent(responseCode, body, headers);
> > > }
> > >
> > > /** {@inheritDoc} */
> > > + @Override
> > > public RemoteContent fetch(RemoteContentRequest request) {
> > > try {
> > > URLConnection fetcher = getConnection(request);
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/CachedContentFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/CachedContentFetcher.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/CachedContentFetcher.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/CachedContentFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,57 @@
> > > +/*
> > > + * 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.shindig.gadgets;
> > > +
> > > +import com.google.inject.Inject;
> > > +import com.google.inject.Singleton;
> > > +
> > > +import java.net.URI;
> > > +import java.util.HashMap;
> > > +import java.util.Map;
> > > +
> > > +/**
> > > + * Caches the results of a request indefinitely.
> > > + *
> > > + * Currently just uses a map for the cache. This means it will grow
> > infinitely.
> > > + */
> > > +@Singleton
> > > +public class CachedContentFetcher extends RemoteContentFetcher {
> > > +
> > > + private final Map<URI, RemoteContent> cache;
> > > +
> > > + /** {@inheritDoc} */
> > > + @Override
> > > + public RemoteContent fetch(RemoteContentRequest request)
> > > + throws GadgetException {
> > > + RemoteContent result = cache.get(request.getUri());
> > > + if (result == null) {
> > > + result = nextFetcher.fetch(request);
> > > + synchronized (cache) {
> > > + cache.put(request.getUri(),result);
> > > + }
> > > + }
> > > + return result;
> > > + }
> > > +
> > > + @Inject
> > > + public CachedContentFetcher(RemoteContentFetcher nextFetcher) {
> > > + super(nextFetcher);
> > > + cache = new HashMap<URI, RemoteContent>();
> > > + }
> > > +}
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,92 @@
> > > +/*
> > > + * 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.shindig.gadgets;
> > > +
> > > +import org.apache.shindig.util.ResourceLoader;
> > > +
> > > +import com.google.inject.AbstractModule;
> > > +import com.google.inject.CreationException;
> > > +import com.google.inject.Scopes;
> > > +import com.google.inject.name.Names;
> > > +import com.google.inject.spi.Message;
> > > +
> > > +import java.io.IOException;
> > > +import java.io.InputStream;
> > > +import java.util.Arrays;
> > > +import java.util.Properties;
> > > +import java.util.concurrent.Executor;
> > > +import java.util.concurrent.Executors;
> > > +
> > > +/**
> > > + * Creates a module to supply all of the Basic* classes
> > > + */
> > > +public class DefaultGuiceModule extends AbstractModule {
> > > + private final Properties properties;
> > > + private final static String DEFAULT_PROPERTIES =
> > "gadgets.properties";
> > > +
> > > + /** {@inheritDoc} */
> > > + @Override
> > > + protected void configure() {
> > > + Names.bindProperties(this.binder(), properties);
> > > +
> > > +
> > bind(RemoteContentFetcher.class).to(BasicRemoteContentFetcher.class);
> > > +
> > > + bind(RemoteContentFetcher.class)
> > > + .annotatedWith(GadgetSpecFetcher.class)
> > > + .to(CachedContentFetcher.class);
> > > + bind(RemoteContentFetcher.class)
> > > + .annotatedWith(MessageBundleFetcher.class)
> > > + .to(CachedContentFetcher.class);
> > > +
> > > + // This is redundant because Guice doesn't handle generic fall
> > through
> > > + // for non-annotated types.
> > > + bind(RemoteContentFetcher.class)
> > > + .annotatedWith(PreloadFetcher.class)
> > > + .to(BasicRemoteContentFetcher.class);
> > > +
> > > + bind(GadgetBlacklist.class).to(BasicGadgetBlacklist.class);
> > > + bind(GadgetTokenDecoder.class).to(BasicGadgetTokenDecoder.class);
> > > + bind(SigningFetcherFactory.class);
> > > + bind(Executor.class).toInstance(Executors.newCachedThreadPool());
> > > +
> > > + bind(SyndicatorConfig.class).in(Scopes.SINGLETON);
> > > + bind(GadgetFeatureRegistry.class).in(Scopes.SINGLETON);
> > > + bind(GadgetServer.class).in(Scopes.SINGLETON);
> > > + }
> > > +
> > > + public DefaultGuiceModule(Properties properties) {
> > > + this.properties = properties;
> > > + }
> > > +
> > > + /**
> > > + * Creates module with standard properties.
> > > + */
> > > + public DefaultGuiceModule() {
> > > + Properties properties = null;
> > > + try {
> > > + InputStream is = ResourceLoader.openResource(DEFAULT_PROPERTIES);
> > > + properties = new Properties();
> > > + properties.load(is);
> > > + } catch (IOException e) {
> > > + throw new CreationException(Arrays.asList(
> > > + new Message("Unable to load properties: " +
> > DEFAULT_PROPERTIES)));
> > > + }
> > > + this.properties = properties;
> > > + }
> > > +}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -34,14 +34,6 @@
> > > * and is modified in parallel by a number of {@code GadgetFeature}
> > > * processors, in an order defined by their dependencies, in
> > > * {@code GadgetServer}.
> > > - *
> > > - * Upon completion of processing, a {@code Gadget} is serialized as
> > appropriate
> > > - * to whatever output format is appropriate (eg. as gadget content in
> > an
> > > - * IFRAME), potentially with post-processing such as HTML whitespace
> > > - * compression or HTML+JS (Caja) rewriting applied.
> > > - *
> > > - * "Hangman" variable substitutions (eg. __MSG_foo__) are performed as
> > needed
> > > - * and transparently for fields that support this functionality.
> > > */
> > > public class Gadget {
> > > private final GadgetContext context;
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetFeatureRegistry.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -17,10 +17,12 @@
> > > */
> > > package org.apache.shindig.gadgets;
> > >
> > > +import com.google.inject.Inject;
> > > +import com.google.inject.name.Named;
> > > +
> > > import java.util.Collections;
> > > import java.util.HashMap;
> > > import java.util.HashSet;
> > > -import java.util.LinkedList;
> > > import java.util.List;
> > > import java.util.Map;
> > > import java.util.Set;
> > > @@ -35,66 +37,33 @@
> > > * registry.register("my-feature", null, new MyFeatureFactory());
> > > */
> > > public class GadgetFeatureRegistry {
> > > - private final Map<String, Entry> features = new HashMap<String,
> > Entry>();
> > > - private final Map<String, Entry> core = new HashMap<String,
> > Entry>();
> > > + private final Map<String, Entry> features;
> > > + private final Map<String, Entry> core;
> > >
> > > // Caches the transitive dependencies to enable faster lookups.
> > > private final Map<Set<String>, Set<Entry>> transitiveDeps
> > > = new HashMap<Set<String>, Set<Entry>>();
> > >
> > > - private boolean coreDone = false;
> > > -
> > > - private final RemoteContentFetcher fetcher;
> > > + private boolean graphComplete = false;
> > >
> > > private final static Logger logger
> > > = Logger.getLogger("org.apache.shindig.gadgets");
> > >
> > > /**
> > > - * Creates the gadget feature registry and loads an initial set of
> > features.
> > > - * Any 'core' features loaded at this point will automatically become
> > > - * dependencies for every other feature.
> > > - * @param featurePath
> > > - * @param fetcher
> > > - */
> > > - public GadgetFeatureRegistry(String featurePath, RemoteContentFetcher
> > fetcher)
> > > - throws GadgetException {
> > > - this.fetcher = fetcher;
> > > - registerFeatures(featurePath);
> > > - }
> > > -
> > > - /**
> > > - * Recursively loads a set of features from a path in the filesystem
> > or
> > > - * from the classpath.
> > > + * Creates a new feature registry and loads the specified features.
> > > *
> > > - * @param featurePath Path to the directory that contains feature xml
> > files.
> > > - */
> > > - public void registerFeatures(String featurePath) throws
> > GadgetException {
> > > - if (featurePath == null) {
> > > - return;
> > > - }
> > > -
> > > - List<String> coreDeps = new LinkedList<String>();
> > > - JsFeatureLoader loader = new JsFeatureLoader(fetcher);
> > > - Set<Entry> jsFeatures = loader.loadFeatures(featurePath, this);
> > > -
> > > - if (!coreDone) {
> > > - for (Entry entry : jsFeatures) {
> > > - if (entry.name.startsWith("core") || entry.name.equals("core"))
> > {
> > > - coreDeps.add(entry.getName());
> > > - core.put(entry.getName(), entry);
> > > - }
> > > - }
> > > -
> > > - logger.info("Core dependencies: " + coreDeps);
> > > -
> > > - // Make sure non-core features depend on core.
> > > - for (Entry entry : jsFeatures) {
> > > - if (!entry.name.startsWith("core") &&
> > !entry.name.equals("core")) {
> > > - entry.deps.addAll(core.keySet());
> > > - }
> > > - }
> > > -
> > > - coreDone = true;
> > > + * @param contentFetcher
> > > + * @param featureFiles
> > > + * @throws GadgetException
> > > + */
> > > + @Inject
> > > + public GadgetFeatureRegistry(@Named("features.default") String
> > featureFiles,
> > > + RemoteContentFetcher contentFetcher) throws GadgetException {
> > > + features = new HashMap<String, Entry>();
> > > + core = new HashMap<String, Entry>();
> > > + if (featureFiles != null) {
> > > + JsFeatureLoader loader = new JsFeatureLoader(contentFetcher);
> > > + loader.loadFeatures(featureFiles, this);
> > > }
> > > }
> > >
> > > @@ -105,7 +74,9 @@
> > > *
> > > * Names are freeform, but it is strongly suggested that they are
> > > * namespaced, optionally (yet often usefully) in Java
> > package-notation ie.
> > > - * 'com.google.gadgets.skins'.
> > > + * 'org.example.FooFeature'
> > > + *
> > > + * May never be invoked after calling getIncludedFeatures.
> > > *
> > > * @param name Name of the feature to register, ideally using the
> > conventions
> > > * described
> > > @@ -116,26 +87,33 @@
> > > */
> > > public Entry register(String name, List<String> deps,
> > > GadgetFeatureFactory feature) {
> > > + if (graphComplete) {
> > > + throw new IllegalStateException("registerFeatures should never be
> > " +
> > > + "invoked after calling getIncludedFeatures");
> > > + }
> > > logger.info("Registering feature: " + name + " with deps " + deps);
> > > Entry entry = new Entry(name, deps, feature, this);
> > > - if (coreDone) {
> > > + if (isCore(entry)) {
> > > + core.put(name, entry);
> > > + for (Entry e : features.values()) {
> > > + e.deps.add(name);
> > > + }
> > > + } else {
> > > entry.deps.addAll(core.keySet());
> > > }
> > > features.put(name, entry);
> > > - validateFeatureGraph();
> > > return entry;
> > > }
> > >
> > > /**
> > > - * Traverses the graph traversed by the registered features,
> > validating
> > > - * that it comprises a directed acyclic graph in which all features'
> > > - * dependencies are provided.
> > > - *
> > > - * If the graph is not acyclic, it cannot be used to create a
> > workflow. If
> > > - * any dependencies are missing, {@code Gadget} rendering may be
> > incomplete.
> > > + * @param entry
> > > + * @return True if the entry is "core" (a dependency of all other
> > features)
> > > */
> > > - private static void validateFeatureGraph() {
> > > - // TODO: ensure that features form a DAG and that all deps are
> > provided
> > > + private boolean isCore(Entry entry) {
> > > + if (entry.name.startsWith("core") || entry.name.equals("core")) {
> > > + return true;
> > > + }
> > > + return false;
> > > }
> > >
> > > /**
> > > @@ -158,6 +136,7 @@
> > > public boolean getIncludedFeatures(Set<String> needed,
> > > Set<Entry> resultsFound,
> > > Set<String> resultsMissing) {
> > > + graphComplete = true;
> > > if (needed.size() == 0) {
> > > // Shortcut for gadgets that don't have any explicit
> > dependencies.
> > > resultsFound.addAll(core.values());
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServer.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -22,7 +22,8 @@
> > > import org.apache.shindig.gadgets.spec.LocaleSpec;
> > > import org.apache.shindig.gadgets.spec.MessageBundle;
> > > import org.apache.shindig.gadgets.spec.Preload;
> > > -import org.apache.shindig.util.Check;
> > > +
> > > +import com.google.inject.Inject;
> > >
> > > import java.util.HashMap;
> > > import java.util.HashSet;
> > > @@ -32,39 +33,42 @@
> > > import java.util.Set;
> > > import java.util.concurrent.Callable;
> > > import java.util.concurrent.CompletionService;
> > > +import java.util.concurrent.Executor;
> > > import java.util.concurrent.ExecutorCompletionService;
> > > import java.util.concurrent.Future;
> > >
> > > +/**
> > > + * Primary gadget processing facility. Converts an input Context into
> > an output
> > > + * Gadget
> > > + */
> > > public class GadgetServer {
> > > - private final GadgetServerConfigReader config;
> > > -
> > > - /**
> > > - * Creates a GadgetServer using the provided configuration.
> > > - *
> > > - * @param configuration
> > > - * @throws IllegalArgumentException When missing required fields
> > aren't set.
> > > - */
> > > - public GadgetServer(GadgetServerConfigReader configuration) {
> > > - Check.notNull(configuration.getExecutor(), "Executor is
> > required.");
> > > - Check.notNull(configuration.getFeatureRegistry(),
> > > - "FeatureRegistry is required.");
> > > - Check.notNull(configuration.getGadgetSpecFetcher(),
> > > - "GadgetSpecFetcher is required");
> > > - Check.notNull(configuration.getMessageBundleFetcher(),
> > > - "MessageBundleFetcher is required.");
> > > - Check.notNull(configuration.getContentFetcher(),
> > > - "ContentFetcher is required.");
> > > - Check.notNull(configuration.getSyndicatorConfig(),
> > > - "SyndicatorConfig is required");
> > > - config = new GadgetServerConfigReader();
> > > - config.copyFrom(configuration);
> > > - }
> > > + private final Executor executor;
> > > + private final GadgetFeatureRegistry registry;
> > > + private final GadgetBlacklist blacklist;
> > > + private final RemoteContentFetcher preloadFetcher;
> > > + private final RemoteContentFetcher gadgetSpecFetcher;
> > > + private final RemoteContentFetcher messageBundleFetcher;
> > >
> > > /**
> > > - * @return A read-only view of the server's configuration.
> > > + * @param executor
> > > + * @param registry
> > > + * @param blacklist
> > > + * @param gadgetSpecFetcher
> > > + * @param messageBundleFetcher
> > > */
> > > - public GadgetServerConfigReader getConfig() {
> > > - return config;
> > > + @Inject
> > > + public GadgetServer(Executor executor,
> > > + GadgetFeatureRegistry registry,
> > > + GadgetBlacklist blacklist,
> > > + @PreloadFetcher RemoteContentFetcher preloadFetcher,
> > > + @GadgetSpecFetcher RemoteContentFetcher gadgetSpecFetcher,
> > > + @MessageBundleFetcher RemoteContentFetcher messageBundleFetcher)
> > {
> > > + this.executor = executor;
> > > + this.registry = registry;
> > > + this.blacklist = blacklist;
> > > + this.preloadFetcher = preloadFetcher;
> > > + this.gadgetSpecFetcher = gadgetSpecFetcher;
> > > + this.messageBundleFetcher = messageBundleFetcher;
> > > }
> > >
> > > /**
> > > @@ -75,13 +79,15 @@
> > > * @throws GadgetException
> > > */
> > > public Gadget processGadget(GadgetContext context) throws
> > GadgetException {
> > > - if (config.getGadgetBlacklist() != null) {
> > > - if (config.getGadgetBlacklist().isBlacklisted(context.getUrl()))
> > {
> > > - throw new
> > GadgetException(GadgetException.Code.BLACKLISTED_GADGET);
> > > - }
> > > + if (blacklist.isBlacklisted(context.getUrl())) {
> > > + throw new
> > GadgetException(GadgetException.Code.BLACKLISTED_GADGET);
> > > }
> > > - GadgetSpec spec =
> > config.getGadgetSpecFetcher().fetch(context.getUrl(),
> > > - context.getIgnoreCache());
> > > +
> > > + RemoteContentRequest request = RemoteContentRequest.getRequest(
> > > + context.getUrl(), context.getIgnoreCache());
> > > + RemoteContent response = gadgetSpecFetcher.fetch(request);
> > > + GadgetSpec spec
> > > + = new GadgetSpec(context.getUrl(),
> > response.getResponseAsString());
> > > return createGadgetFromSpec(spec, context);
> > > }
> > >
> > > @@ -94,9 +100,10 @@
> > > */
> > > private MessageBundle getBundle(LocaleSpec localeSpec, GadgetContext
> > context)
> > > throws GadgetException {
> > > - MessageBundle bundle;
> > > - bundle = config.getMessageBundleFetcher().fetch(
> > > + RemoteContentRequest request = RemoteContentRequest.getRequest(
> > > localeSpec.getMessages(), context.getIgnoreCache());
> > > + RemoteContent response = messageBundleFetcher.fetch(request);
> > > + MessageBundle bundle = new
> > MessageBundle(response.getResponseAsString());
> > > return bundle;
> > > }
> > >
> > > @@ -178,17 +185,22 @@
> > > Map<GadgetFeatureRegistry.Entry, GadgetFeature> tasks)
> > > throws GadgetException {
> > >
> > > - // Immediately enqueue all the preloads
> > > - CompletionService<RemoteContent> preloadProcessor
> > > - = new
> > ExecutorCompletionService<RemoteContent>(config.getExecutor());
> > > - for (Preload preload :
> > gadget.getSpec().getModulePrefs().getPreloads()) {
> > > - gadget.getPreloadMap().put(preload,
> > > - preloadProcessor.submit(
> > > - new PreloadTask(preload,
> > getConfig().getContentFetcher())));
> > > + // Immediately enqueue all the preloads. We don't block on preloads
> > because
> > > + // we want them to run in parallel
> > > + RenderingContext renderContext =
> > gadget.getContext().getRenderingContext();
> > > + if (RenderingContext.GADGET.equals(renderContext)) {
> > > + CompletionService<RemoteContent> preloadProcessor
> > > + = new ExecutorCompletionService<RemoteContent>(executor);
> > > + for (Preload preload :
> > gadget.getSpec().getModulePrefs().getPreloads()) {
> > > + PreloadTask task = new PreloadTask(preload, preloadFetcher);
> > > + Future<RemoteContent> future = preloadProcessor.submit(task);
> > > + gadget.getPreloadMap().put(preload, future);
> > > + }
> > > }
> > >
> > > + // TODO: This seems pointless if nothing is actually using it.
> > > CompletionService<GadgetException> featureProcessor
> > > - = new
> > ExecutorCompletionService<GadgetException>(config.getExecutor());
> > > + = new ExecutorCompletionService<GadgetException>(executor);
> > > // FeatureTask is OK has a hash key because we want actual
> > instances, not
> > > // names.
> > > GadgetContext context = gadget.getContext();
> > > @@ -251,8 +263,7 @@
> > > Set<GadgetFeatureRegistry.Entry> dependencies
> > > = new HashSet<GadgetFeatureRegistry.Entry>(features.size());
> > > Set<String> unsupported = new HashSet<String>();
> > > - config.getFeatureRegistry().getIncludedFeatures(features.keySet(),
> > > - dependencies, unsupported);
> > > + registry.getIncludedFeatures(features.keySet(), dependencies,
> > unsupported);
> > >
> > > for (String missing : unsupported) {
> > > Feature feature = features.get(missing);
> > > @@ -319,7 +330,11 @@
> > >
> > > public RemoteContent call() {
> > > RemoteContentRequest request = new
> > RemoteContentRequest(preload.getHref());
> > > - return fetcher.fetch(request);
> > > + try {
> > > + return fetcher.fetch(request);
> > > + } catch (GadgetException e) {
> > > + return RemoteContent.ERROR;
> > > + }
> > > }
> > >
> > > public PreloadTask(Preload preload, RemoteContentFetcher fetcher) {
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfig.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfig.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfig.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfig.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -1,88 +0,0 @@
> > > -/**
> > > - * 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.shindig.gadgets;
> > > -
> > > -import org.apache.shindig.gadgets.spec.GadgetSpec;
> > > -import org.apache.shindig.gadgets.spec.MessageBundle;
> > > -
> > > -import java.util.concurrent.Executor;
> > > -
> > > -/**
> > > - * Stores configuration data for a GadgetServer.
> > > - *
> > > - * The main purpose of this class is to allow for better readability of
> > > - * GadgetServer ctor parameters and to simplify interacting with its
> > components.
> > > - *
> > > - *
> > > - *
> > > - * Usage:
> > > - *
> > > - * <code>
> > > - * GadgetServer server = new GadgetServer(new GadgetServerConfig()
> > > - * .setRemoteContentFetcher(new BasicRemoteContentFetcher())
> > > - * .setGadgetCache(new BasicGadgetDataCache<GadgetSpec>())
> > > - * .setOtherProperties(...));
> > > - * </code>
> > > - *
> > > - * Any missing data will result in GadgetServer throwing an
> > IllegalArgsException
> > > - * unless noted as "optional" here.
> > > - */
> > > -public class GadgetServerConfig extends GadgetServerConfigReader {
> > > -
> > > - public GadgetServerConfig setExecutor(Executor executor) {
> > > - this.executor = executor;
> > > - return this;
> > > - }
> > > -
> > > - public GadgetServerConfig setFeatureRegistry(
> > > - GadgetFeatureRegistry featureRegistry) {
> > > - this.featureRegistry = featureRegistry;
> > > - return this;
> > > - }
> > > -
> > > - public GadgetServerConfig setGadgetSpecFetcher(
> > > - DataFetcher<GadgetSpec> gadgetSpecFetcher) {
> > > - this.gadgetSpecFetcher = gadgetSpecFetcher;
> > > - return this;
> > > - }
> > > -
> > > - public GadgetServerConfig setMessageBundleFetcher(
> > > - DataFetcher<MessageBundle> messageBundleFetcher) {
> > > - this.messageBundleFetcher = messageBundleFetcher;
> > > - return this;
> > > - }
> > > -
> > > - public GadgetServerConfig setContentFetcher(
> > > - RemoteContentFetcher contentFetcher) {
> > > - this.contentFetcher = contentFetcher;
> > > - return this;
> > > - }
> > > -
> > > - // Optional
> > > -
> > > - public GadgetServerConfig setGadgetBlacklist(
> > > - GadgetBlacklist gadgetBlacklist) {
> > > - this.gadgetBlacklist = gadgetBlacklist;
> > > - return this;
> > > - }
> > > -
> > > - public GadgetServerConfig setSyndicatorConfig(SyndicatorConfig
> > config) {
> > > - syndicatorConfig = config;
> > > - return this;
> > > - }
> > > -}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfigReader.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfigReader.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfigReader.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetServerConfigReader.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -1,96 +0,0 @@
> > > -/**
> > > - * 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.shindig.gadgets;
> > > -
> > > -import org.apache.shindig.gadgets.spec.GadgetSpec;
> > > -import org.apache.shindig.gadgets.spec.MessageBundle;
> > > -
> > > -import java.util.concurrent.Executor;
> > > -
> > > -/**
> > > - * Stores configuration data for a GadgetServer.
> > > - *
> > > - * The main purpose of this class is to allow for better readability of
> > > - * GadgetServer ctor parameters and to simplify interacting with its
> > components.
> > > - *
> > > - * Works in conjunction with {@code GadgetServerConfig} to create
> > immutable
> > > - * configuration objects. Note that members are still potentially
> > mutable.
> > > - *
> > > - */
> > > -public class GadgetServerConfigReader {
> > > -
> > > - protected Executor executor;
> > > -
> > > - public Executor getExecutor() {
> > > - return executor;
> > > - }
> > > -
> > > - protected GadgetFeatureRegistry featureRegistry;
> > > -
> > > - public GadgetFeatureRegistry getFeatureRegistry() {
> > > - return featureRegistry;
> > > - }
> > > -
> > > - protected DataFetcher<GadgetSpec> gadgetSpecFetcher;
> > > -
> > > - public DataFetcher<GadgetSpec> getGadgetSpecFetcher() {
> > > - return gadgetSpecFetcher;
> > > - }
> > > -
> > > - protected DataFetcher<MessageBundle> messageBundleFetcher;
> > > -
> > > - public DataFetcher<MessageBundle> getMessageBundleFetcher() {
> > > - return messageBundleFetcher;
> > > - }
> > > -
> > > - protected RemoteContentFetcher contentFetcher;
> > > -
> > > - public RemoteContentFetcher getContentFetcher() {
> > > - return contentFetcher;
> > > - }
> > > -
> > > - protected GadgetBlacklist gadgetBlacklist;
> > > -
> > > - public GadgetBlacklist getGadgetBlacklist() {
> > > - return gadgetBlacklist;
> > > - }
> > > -
> > > - protected SyndicatorConfig syndicatorConfig;
> > > -
> > > - public SyndicatorConfig getSyndicatorConfig() {
> > > - if (syndicatorConfig == null) {
> > > - return SyndicatorConfig.EMPTY;
> > > - }
> > > - return syndicatorConfig;
> > > - }
> > > -
> > > - /**
> > > - * Copies all fields from {@code base} into this instance.
> > > - * @param base
> > > - */
> > > - public void copyFrom(GadgetServerConfigReader base) {
> > > - // We use the getters here just in case any methods were
> > overridden.
> > > - executor = base.getExecutor();
> > > - featureRegistry = base.getFeatureRegistry();
> > > - contentFetcher = base.getContentFetcher();
> > > - gadgetSpecFetcher = base.getGadgetSpecFetcher();
> > > - messageBundleFetcher = base.getMessageBundleFetcher();
> > > - gadgetBlacklist = base.getGadgetBlacklist();
> > > - syndicatorConfig = base.getSyndicatorConfig();
> > > - }
> > > -}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecFetcher.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecFetcher.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetSpecFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -19,62 +19,15 @@
> > >
> > > package org.apache.shindig.gadgets;
> > >
> > > -import org.apache.shindig.gadgets.spec.GadgetSpec;
> > > +import com.google.inject.BindingAnnotation;
> > >
> > > -import java.net.URI;
> > > -import java.util.HashMap;
> > > -import java.util.Map;
> > > -import java.util.logging.Logger;
> > > -
> > > -/**
> > > - * Spec retrieval implementation that retrieves specs by the following:
> > > - *
> > > - * - Consulting the in-memory cache (just a Map)
> > > - * - If not found, making a RemoteContentRequest for the spec
> > > - * - Parsing spec
> > > - * - Storing to the cache
> > > - */
> > > -public class GadgetSpecFetcher implements DataFetcher<GadgetSpec> {
> > > - private final RemoteContentFetcher fetcher;
> > > - private final Map<URI, GadgetSpec> cache;
> > > -
> > > - private final static Logger logger
> > > - = Logger.getLogger("org.apache.shindig.gadgets");
> > > -
> > > - /** {@inheritDoc} */
> > > - public void invalidate(URI url) {
> > > - synchronized (cache) {
> > > - cache.remove(url);
> > > - }
> > > - }
> > > -
> > > - /** {@inheritDoc} */
> > > - public GadgetSpec fetch(URI url, boolean forceReload) throws
> > GadgetException {
> > > - GadgetSpec spec = null;
> > > - if (!forceReload) {
> > > - spec = cache.get(url);
> > > - }
> > > - if (spec == null) {
> > > - RemoteContentRequest request = new RemoteContentRequest(url);
> > > - RemoteContent response = fetcher.fetch(request);
> > > -
> > > - if (response.getHttpStatusCode() == RemoteContent.SC_OK) {
> > > - spec = new GadgetSpec(url, response.getResponseAsString());
> > > - cache.put(url, spec);
> > > - } else {
> > > - String error = "Unable to get content from " + url.toString();
> > > - throw new GadgetException(
> > > - GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, error);
> > > - }
> > > - }
> > > - return spec;
> > > - }
> > > -
> > > - /**
> > > - * @param fetcher The fetcher to use for remote resource retrieval.
> > > - */
> > > - public GadgetSpecFetcher(RemoteContentFetcher fetcher) {
> > > - this.fetcher = fetcher;
> > > - cache = new HashMap<URI, GadgetSpec>();
> > > - }
> > > +import java.lang.annotation.ElementType;
> > > +import java.lang.annotation.Retention;
> > > +import java.lang.annotation.RetentionPolicy;
> > > +import java.lang.annotation.Target;
> > > +
> > > +@Retention(RetentionPolicy.RUNTIME)
> > > +@Target({ElementType.FIELD, ElementType.PARAMETER})
> > > +@BindingAnnotation
> > > +public @interface GadgetSpecFetcher {
> > > }
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetToken.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetToken.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetToken.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetToken.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -20,7 +20,7 @@
> > >
> > > /**
> > > * An abstract representation of a signing token.
> > > - * Use in conjunction with @code GadgetSigner.
> > > + * Use in conjunction with @code GadgetTokenDecoder.
> > > */
> > > public interface GadgetToken {
> > >
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetTokenDecoder.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetTokenDecoder.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetTokenDecoder.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetTokenDecoder.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,34 @@
> > > +/*
> > > + * 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.shindig.gadgets;
> > > +
> > > +/**
> > > + * Handles verification of gadget security tokens.
> > > + */
> > > +public interface GadgetTokenDecoder {
> > > +
> > > + /**
> > > + * Decrypts and verifies a gadget security token to return a gadget
> > token.
> > > + *
> > > + * @param tokenString String representation of the token to be
> > created.
> > > + * @return The token representation of the input data.
> > > + * @throws GadgetException If tokenString is not a valid token
> > > + */
> > > + public GadgetToken createToken(String tokenString) throws
> > GadgetException;
> > > +}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsFeatureLoader.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -26,7 +26,11 @@
> > >
> > > import java.io.File;
> > > import java.io.IOException;
> > > -import java.util.*;
> > > +import java.util.EnumMap;
> > > +import java.util.HashMap;
> > > +import java.util.LinkedList;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > import java.util.logging.Logger;
> > >
> > > /**
> > > @@ -59,18 +63,18 @@
> > > * in the text file. If path is prefixed with res://, the file
> > > * is treated as a resource, and all references are assumed to be
> > > * resources as well.
> > > - * @return A list of the newly loaded features.
> > > * @throws GadgetException
> > > */
> > > - public Set<GadgetFeatureRegistry.Entry> loadFeatures(String path,
> > > - GadgetFeatureRegistry registry) throws GadgetException {
> > > + public void loadFeatures(String path, GadgetFeatureRegistry registry)
> > > + throws GadgetException {
> > > List<ParsedFeature> features = new LinkedList<ParsedFeature>();
> > > try {
> > > if (path.startsWith("res://")) {
> > > path = path.substring(6);
> > > logger.info("Loading resources from: " + path);
> > > if (path.endsWith(".txt")) {
> > > -
> > loadResources(ResourceLoader.getContent(path).split("[\r\n]+"), features);
> > > +
> > loadResources(ResourceLoader.getContent(path).split("[\r\n]+"),
> > > + features);
> > > } else {
> > > loadResources(new String[]{path}, features);
> > > }
> > > @@ -83,14 +87,11 @@
> > > throw new GadgetException(GadgetException.Code.INVALID_PATH, e);
> > > }
> > >
> > > - Set<GadgetFeatureRegistry.Entry> entries
> > > - = new HashSet<GadgetFeatureRegistry.Entry>();
> > > for (ParsedFeature feature : features) {
> > > JsLibraryFeatureFactory factory
> > > = new JsLibraryFeatureFactory(feature.libraries);
> > > - entries.add(registry.register(feature.name, feature.deps,
> > factory));
> > > + registry.register(feature.name, feature.deps, factory);
> > > }
> > > - return entries;
> > > }
> > >
> > > /**
> > > @@ -213,7 +214,8 @@
> > >
> > > NodeList gadgets = doc.getElementsByTagName("gadget");
> > > for (int i = 0, j = gadgets.getLength(); i < j; ++i) {
> > > - processContext(feature, (Element)gadgets.item(i),
> > RenderingContext.GADGET);
> > > + processContext(feature, (Element)gadgets.item(i),
> > > + RenderingContext.GADGET);
> > > }
> > >
> > > NodeList containers = doc.getElementsByTagName("container");
> > > @@ -236,9 +238,11 @@
> > > * @param feature
> > > * @param context
> > > * @param renderingContext
> > > + * @throws GadgetException
> > > */
> > > private void processContext(ParsedFeature feature, Element context,
> > > - RenderingContext renderingContext) {
> > > + RenderingContext renderingContext)
> > > + throws GadgetException {
> > > String syndicator = XmlUtil.getAttribute(context, "synd",
> > > SyndicatorConfig.DEFAULT_SYNDICATOR);
> > > NodeList libraries = context.getElementsByTagName("script");
> > > @@ -298,7 +302,8 @@
> > > final List<String> deps;
> > >
> > > public ParsedFeature() {
> > > - libraries = new EnumMap<RenderingContext, Map<String,
> > List<JsLibrary>>>(RenderingContext.class);
> > > + libraries = new EnumMap<RenderingContext, Map<String,
> > List<JsLibrary>>>(
> > > + RenderingContext.class);
> > > deps = new LinkedList<String>();
> > > }
> > >
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/JsLibrary.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -113,9 +113,10 @@
> > > * kept as a url reference, otherwise the file will be fetched
> > and treated
> > > * as a FILE type.
> > > * @return The newly created library.
> > > + * @throws GadgetException
> > > */
> > > public static JsLibrary create(Type type, String content, String
> > feature,
> > > - RemoteContentFetcher fetcher) {
> > > + RemoteContentFetcher fetcher) throws GadgetException {
> > > String optimizedContent = null;
> > > String debugContent;
> > > switch (type) {
> > > @@ -168,9 +169,10 @@
> > > * @param url
> > > * @param fetcher
> > > * @return The contents of the JS file, or null if it can't be
> > fetched.
> > > + * @throws GadgetException
> > > */
> > > private static String loadDataFromUrl(String url,
> > > - RemoteContentFetcher fetcher) {
> > > + RemoteContentFetcher fetcher) throws GadgetException {
> > > try {
> > > logger.info("Attempting to load js from: " + url);
> > > URI uri = new URI(url);
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleFetcher.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleFetcher.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/MessageBundleFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -19,63 +19,15 @@
> > >
> > > package org.apache.shindig.gadgets;
> > >
> > > -import org.apache.shindig.gadgets.spec.MessageBundle;
> > > +import com.google.inject.BindingAnnotation;
> > >
> > > -import java.net.URI;
> > > -import java.util.HashMap;
> > > -import java.util.Map;
> > > -import java.util.logging.Logger;
> > > -
> > > -/**
> > > - * Message bundle retrieval implementation that retrieves by the
> > following:
> > > - *
> > > - * - Consulting the in-memory cache (just a Map)
> > > - * - If not found, making a RemoteContentRequest for the bundle
> > > - * - Parsing bundle
> > > - * - Storing to the cache
> > > - */
> > > -public class MessageBundleFetcher implements DataFetcher<MessageBundle>
> > {
> > > - private final RemoteContentFetcher fetcher;
> > > - private final Map<URI, MessageBundle> cache;
> > > -
> > > - private final static Logger logger
> > > - = Logger.getLogger("org.apache.shindig.gadgets");
> > > -
> > > - /** {@inheritDoc} */
> > > - public void invalidate(URI url) {
> > > - synchronized (cache) {
> > > - cache.remove(url);
> > > - }
> > > - }
> > > -
> > > - /** {@inheritDoc} */
> > > - public MessageBundle fetch(URI url, boolean forceReload)
> > > - throws GadgetException {
> > > - MessageBundle bundle = null;
> > > - if (!forceReload) {
> > > - bundle = cache.get(url);
> > > - }
> > > - if (bundle == null) {
> > > - RemoteContentRequest request = new RemoteContentRequest(url);
> > > - RemoteContent response = fetcher.fetch(request);
> > > -
> > > - if (response.getHttpStatusCode() == RemoteContent.SC_OK) {
> > > - bundle = new MessageBundle(response.getResponseAsString());
> > > - cache.put(url, bundle);
> > > - } else {
> > > - String error = "Unable to get content from " + url.toString();
> > > - throw new GadgetException(
> > > - GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, error);
> > > - }
> > > - }
> > > - return bundle;
> > > - }
> > > -
> > > - /**
> > > - * @param fetcher The fetcher to use for remote resource retrieval.
> > > - */
> > > - public MessageBundleFetcher(RemoteContentFetcher fetcher) {
> > > - this.fetcher = fetcher;
> > > - cache = new HashMap<URI, MessageBundle>();
> > > - }
> > > +import java.lang.annotation.ElementType;
> > > +import java.lang.annotation.Retention;
> > > +import java.lang.annotation.RetentionPolicy;
> > > +import java.lang.annotation.Target;
> > > +
> > > +@Retention(RetentionPolicy.RUNTIME)
> > > +@Target({ElementType.FIELD, ElementType.PARAMETER})
> > > +@BindingAnnotation
> > > +public @interface MessageBundleFetcher {
> > > }
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloadFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloadFetcher.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloadFetcher.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/PreloadFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,33 @@
> > > +/*
> > > + * 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.shindig.gadgets;
> > > +
> > > +import com.google.inject.BindingAnnotation;
> > > +
> > > +import java.lang.annotation.ElementType;
> > > +import java.lang.annotation.Retention;
> > > +import java.lang.annotation.RetentionPolicy;
> > > +import java.lang.annotation.Target;
> > > +
> > > +@Retention(RetentionPolicy.RUNTIME)
> > > +@Target({ElementType.FIELD, ElementType.PARAMETER})
> > > +@BindingAnnotation
> > > +public @interface PreloadFetcher {
> > > +}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContent.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -89,6 +89,16 @@
> > > }
> > >
> > > /**
> > > + * Simple constructor for setting a basic response from a string.
> > Mostly used
> > > + * for testing.
> > > + *
> > > + * @param body
> > > + */
> > > + public RemoteContent(String body) {
> > > + this(SC_OK, body.getBytes(), null);
> > > + }
> > > +
> > > + /**
> > > * Attempts to determine the encoding of the body. If it can't be
> > determined,
> > > * we use DEFAULT_ENCODING instead.
> > > * @return The detected encoding or DEFAULT_ENCODING.
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentFetcher.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentFetcher.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -18,11 +18,30 @@
> > > package org.apache.shindig.gadgets;
> > >
> > >
> > > -public interface RemoteContentFetcher {
> > > +/**
> > > + * Fetches data over HTTP.
> > > + *
> > > + * Subclasses can use a chain-of-responsibility pattern to add
> > functionality
> > > + * to the fetching process. For example, a SigningFetcher can talk to
> > a
> > > + * CachingFetcher can talk to a ThrottlingFetcher that talks to a
> > > + * RemoteFetcher that gets the actual data.
> > > + */
> > > +public abstract class RemoteContentFetcher {
> > > +
> > > + /** next fetcher in the chain, may be null */
> > > + protected RemoteContentFetcher nextFetcher;
> > > +
> > > + protected RemoteContentFetcher(RemoteContentFetcher nextFetcher) {
> > > + this.nextFetcher = nextFetcher;
> > > + }
> > > +
> > > /**
> > > - * Fetch content using the HTTP GET method
> > > + * Fetch HTTP content.
> > > + *
> > > * @param request The request to fetch.
> > > * @return RemoteContent
> > > + * @throws GadgetException
> > > */
> > > - public RemoteContent fetch(RemoteContentRequest request);
> > > + public abstract RemoteContent fetch(RemoteContentRequest request)
> > > + throws GadgetException;
> > > }
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentRequest.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentRequest.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentRequest.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RemoteContentRequest.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -21,6 +21,7 @@
> > >
> > > import java.io.ByteArrayInputStream;
> > > import java.io.InputStream;
> > > +import java.io.UnsupportedEncodingException;
> > > import java.net.URI;
> > > import java.util.ArrayList;
> > > import java.util.Arrays;
> > > @@ -33,9 +34,6 @@
> > > * Holds request data for passing to a RemoteContentFetcher.
> > > * Instances of this object are immutable.
> > > *
> > > - * TODO: We should probably just stick the method in here. Having
> > separate
> > > - * calls for POST vs. get seems unnecessary.
> > > - *
> > > * TODO: This naming seems really ridiculous now. Why don't we just
> > call it
> > > * what it is -- an HTTP request?
> > > */
> > > @@ -50,6 +48,19 @@
> > > }
> > >
> > > /**
> > > + * @return The post body as a string, assuming UTF-8 encoding.
> > > + * TODO: We should probably tolerate other encodings, based on the
> > > + * Content-Type header.
> > > + */
> > > + public String getPostBodyAsString() {
> > > + try {
> > > + return new String(postBody, "UTF-8");
> > > + } catch (UnsupportedEncodingException e) {
> > > + return "";
> > > + }
> > > + }
> > > +
> > > + /**
> > > * Retrieves the total length of the post body.
> > > *
> > > * @return The length of the post body.
> > > @@ -121,6 +132,18 @@
> > > }
> > >
> > > /**
> > > + * Creates a simple GET request
> > > + *
> > > + * @param uri
> > > + * @param ignoreCache
> > > + */
> > > + public static RemoteContentRequest getRequest(URI uri, boolean
> > ignoreCache) {
> > > + Options options = new Options();
> > > + options.ignoreCache = ignoreCache;
> > > + return new RemoteContentRequest(uri, options);
> > > + }
> > > +
> > > + /**
> > > *
> > > * @param method
> > > * @param uri
> > > @@ -165,6 +188,22 @@
> > > }
> > >
> > > /**
> > > + * Creates a new request to a different URL using all request data
> > from
> > > + * an existing request.
> > > + *
> > > + * @param uri
> > > + * @param base The base request to copy data from.
> > > + */
> > > + public RemoteContentRequest(URI uri, RemoteContentRequest base) {
> > > + this.uri = uri;
> > > + this.method = base.method;
> > > + this.options = base.options;
> > > + this.headers = base.headers;
> > > + this.contentType = base.contentType;
> > > + this.postBody = base.postBody;
> > > + }
> > > +
> > > + /**
> > > * Basic GET request.
> > > *
> > > * @param uri
> > > @@ -285,6 +324,10 @@
> > > }
> > >
> > > public static final Options DEFAULT_OPTIONS = new Options();
> > > + public static final Options IGNORE_CACHE_OPTIONS = new Options();
> > > + static {
> > > + IGNORE_CACHE_OPTIONS.ignoreCache = true;
> > > + }
> > >
> > > /**
> > > * Bag of options for making a request.
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -18,6 +18,15 @@
> > > package org.apache.shindig.gadgets;
> > >
> > > public enum RenderingContext {
> > > + // Used when rendering gadgets (iframes or inline).
> > > + // TODO: rename this to "RENDER_GADGET"?
> > > GADGET,
> > > - CONTAINER
> > > +
> > > + // Used when rendering container data (not a gadget render)
> > > + CONTAINER,
> > > +
> > > + // Used when retrieving metadata about a gadget. Processing is
> > generally
> > > + // identical to processing under GADGET, but some operations may be
> > safely
> > > + // skipped, such as preload processing.
> > > + METADATA
> > > }
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,284 @@
> > > +/*
> > > + * 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 org.apache.shindig.gadgets;
> > > +
> > > +import org.apache.shindig.util.Crypto;
> > > +import org.apache.shindig.util.TimeSource;
> > > +
> > > +import net.oauth.OAuth;
> > > +import net.oauth.OAuthAccessor;
> > > +import net.oauth.OAuthConsumer;
> > > +import net.oauth.OAuthMessage;
> > > +import net.oauth.OAuth.Parameter;
> > > +import net.oauth.signature.RSA_SHA1;
> > > +
> > > +import java.net.URI;
> > > +import java.net.URISyntaxException;
> > > +import java.net.URL;
> > > +import java.security.PrivateKey;
> > > +import java.util.ArrayList;
> > > +import java.util.HashSet;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +import java.util.regex.Pattern;
> > > +
> > > +/**
> > > + * Implements signed fetch based on the OAuth request signing
> > algorithm.
> > > + *
> > > + * Subclasses can override signMessage to use their own crypto if they
> > don't
> > > + * like the oauth.net code for some reason.
> > > + *
> > > + * Instances of this class are only accessed by a single thread at a
> > time,
> > > + * but instances may be created by multiple threads.
> > > + */
> > > +public class SigningFetcher extends RemoteContentFetcher {
> > > +
> > > + protected static final String OPENSOCIAL_OWNERID =
> > "opensocial_owner_id";
> > > +
> > > + protected static final String OPENSOCIAL_VIEWERID =
> > "opensocial_viewer_id";
> > > +
> > > + protected static final String OPENSOCIAL_APPID = "opensocial_app_id";
> > > +
> > > + protected static final String XOAUTH_PUBLIC_KEY
> > > + = "xoauth_signature_publickey";
> > > +
> > > + protected static final Pattern ALLOWED_PARAM_NAME = Pattern
> > > + .compile("[\\w_\\-]+");
> > > +
> > > + protected final TimeSource clock = new TimeSource();
> > > +
> > > + /**
> > > + * Authentication token for the user and gadget making the request.
> > > + */
> > > + protected final GadgetToken authToken;
> > > +
> > > + /**
> > > + * Private key we pass to the OAuth RSA_SHA1 algorithm. This can be
> > a
> > > + * PrivateKey object, or a PEM formatted private key, or a DER
> > encoded byte
> > > + * array for the private key. (No, really, they accept any of them.)
> > > + */
> > > + protected final Object privateKeyObject;
> > > +
> > > + /**
> > > + * The name of the key, included in the fetch to help with key
> > rotation.
> > > + */
> > > + protected final String keyName;
> > > +
> > > + /**
> > > + * Constructor for subclasses that don't want this code to use their
> > > + * keys.
> > > + */
> > > + protected SigningFetcher(RemoteContentFetcher next, GadgetToken
> > authToken) {
> > > + this(next, authToken, null, null);
> > > + }
> > > +
> > > + /**
> > > + * Constructor based on signing with the given PrivateKey object.
> > > + *
> > > + * @param authToken verified gadget security token
> > > + * @param keyName name of the key to include in the request
> > > + * @param privateKey the key to use for the signing
> > > + */
> > > + public static SigningFetcher makeFromPrivateKey(RemoteContentFetcher
> > next,
> > > + GadgetToken authToken, String keyName, PrivateKey privateKey) {
> > > + return new SigningFetcher(next, authToken, keyName, privateKey);
> > > + }
> > > +
> > > + /**
> > > + * Constructor based on signing with the given PrivateKey object.
> > > + *
> > > + * @param authToken verified gadget security token
> > > + * @param keyName name of the key to include in the request
> > > + * @param privateKey base64 encoded private key
> > > + */
> > > + public static SigningFetcher
> > makeFromB64PrivateKey(RemoteContentFetcher next,
> > > + GadgetToken authToken, String keyName, String privateKey) {
> > > + return new SigningFetcher(next, authToken, keyName, privateKey);
> > > + }
> > > +
> > > + /**
> > > + * Constructor based on signing with the given PrivateKey object.
> > > + *
> > > + * @param authToken verified gadget security token
> > > + * @param keyName name of the key to include in the request
> > > + * @param privateKey DER encoded private key
> > > + */
> > > + public static SigningFetcher makeFromPrivateKeyBytes(
> > > + RemoteContentFetcher next, GadgetToken authToken, String keyName,
> > > + byte[] privateKey) {
> > > + return new SigningFetcher(next, authToken, keyName, privateKey);
> > > + }
> > > +
> > > + protected SigningFetcher(RemoteContentFetcher next, GadgetToken
> > authToken,
> > > + String keyName, Object privateKeyObject) {
> > > + super(next);
> > > + this.authToken = authToken;
> > > + this.keyName = keyName;
> > > + this.privateKeyObject = privateKeyObject;
> > > + }
> > > +
> > > + @Override
> > > + public RemoteContent fetch(RemoteContentRequest request)
> > > + throws GadgetException {
> > > + RemoteContentRequest signed = signRequest(request);
> > > + return nextFetcher.fetch(signed);
> > > + }
> > > +
> > > + private RemoteContentRequest signRequest(RemoteContentRequest req)
> > > + throws GadgetException {
> > > + try {
> > > + // Parse the request into parameters for OAuth signing, stripping
> > out
> > > + // any OAuth or OpenSocial parameters injected by the client
> > > + URI resource = req.getUri();
> > > + String query = resource.getRawQuery();
> > > + resource = removeQuery(resource);
> > > + List<OAuth.Parameter> queryParams =
> > sanitize(OAuth.decodeForm(query));
> > > + String postStr = req.getPostBodyAsString();
> > > + List<OAuth.Parameter> postParams =
> > sanitize(OAuth.decodeForm(postStr));
> > > + List<OAuth.Parameter> msgParams = new
> > ArrayList<OAuth.Parameter>();
> > > + msgParams.addAll(queryParams);
> > > + msgParams.addAll(postParams);
> > > +
> > > + addOpenSocialParams(msgParams);
> > > +
> > > + addOAuthParams(msgParams);
> > > +
> > > + // Build and sign the OAuthMessage; note that the resource here
> > has
> > > + // no query string, the parameters are all in msgParams
> > > + OAuthMessage message
> > > + = new OAuthMessage(req.getMethod(), resource.toString(),
> > msgParams);
> > > +
> > > + // Sign the message, this may jump into a subclass
> > > + signMessage(message);
> > > +
> > > + // Rebuild the query string, including all of the parameters we
> > added.
> > > + // We have to be careful not to copy POST parameters into the
> > query.
> > > + // If post and query parameters share a name, they end up being
> > removed
> > > + // from the query.
> > > + HashSet<String> forPost = new HashSet<String>();
> > > + for (OAuth.Parameter param : postParams) {
> > > + forPost.add(param.getKey());
> > > + }
> > > + List<Map.Entry<String, String>> newQuery =
> > > + new ArrayList<Map.Entry<String, String>>();
> > > + for (Map.Entry<String, String> param : message.getParameters()) {
> > > + if (! forPost.contains(param.getKey())) {
> > > + newQuery.add(param);
> > > + }
> > > + }
> > > + // Careful here; the OAuth form encoding scheme is slightly
> > different than
> > > + // the normal form encoding scheme, so we have to use the OAuth
> > library
> > > + // formEncode method. The java.net.URI code makes it difficult
> > to insert
> > > + // a pre-encoded query string, so we use URL instead.
> > > + String finalQuery = OAuth.formEncode(newQuery);
> > > + URL url = new URL(
> > > + resource.getScheme(),
> > > + resource.getHost(),
> > > + resource.getPort(),
> > > + resource.getRawPath() + "?" + finalQuery);
> > > + return new RemoteContentRequest(url.toURI(), req);
> > > + } catch (Exception e) {
> > > + throw new
> > GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR, e);
> > > + }
> > > + }
> > > +
> > > + private URI removeQuery(URI resource) throws URISyntaxException {
> > > + return new URI(
> > > + resource.getScheme(),
> > > + null, // user info
> > > + resource.getHost(),
> > > + resource.getPort(),
> > > + resource.getRawPath(),
> > > + null, // query
> > > + null); // fragment
> > > + }
> > > +
> > > +
> > > + private void addOpenSocialParams(List<Parameter> msgParams) {
> > > + String owner = authToken.getOwnerId();
> > > + if (owner != null) {
> > > + msgParams.add(new OAuth.Parameter(OPENSOCIAL_OWNERID, owner));
> > > + }
> > > +
> > > + String viewer = authToken.getViewerId();
> > > + if (viewer != null) {
> > > + msgParams.add(new OAuth.Parameter(OPENSOCIAL_VIEWERID, viewer));
> > > + }
> > > +
> > > + String app = authToken.getAppId();
> > > + if (app != null) {
> > > + msgParams.add(new OAuth.Parameter(OPENSOCIAL_APPID, app));
> > > + }
> > > +
> > > + }
> > > +
> > > + private void addOAuthParams(List<Parameter> msgParams) {
> > > + msgParams.add(new OAuth.Parameter(OAuth.OAUTH_TOKEN, ""));
> > > +
> > > + String domain = authToken.getDomain();
> > > + if (domain != null) {
> > > + msgParams.add(new OAuth.Parameter(OAuth.OAUTH_CONSUMER_KEY,
> > domain));
> > > + }
> > > +
> > > + if (keyName != null) {
> > > + msgParams.add(new OAuth.Parameter(XOAUTH_PUBLIC_KEY, keyName));
> > > + }
> > > +
> > > + String nonce = Long.toHexString(Crypto.rand.nextLong());
> > > + msgParams.add(new OAuth.Parameter(OAuth.OAUTH_NONCE, nonce));
> > > +
> > > + String timestamp = Long.toString(clock.currentTimeMillis()/1000L);
> > > + msgParams.add(new OAuth.Parameter(OAuth.OAUTH_TIMESTAMP,
> > timestamp));
> > > +
> > > + msgParams.add(new OAuth.Parameter(OAuth.OAUTH_SIGNATURE_METHOD,
> > > + OAuth.RSA_SHA1));
> > > + }
> > > +
> > > + /**
> > > + * Sign a message and append the oauth signature parameter to the
> > message
> > > + * object.
> > > + *
> > > + * @param message the message to sign
> > > + *
> > > + * @throws Exception because the OAuth libraries require it.
> > > + */
> > > + protected void signMessage(OAuthMessage message) throws Exception {
> > > + OAuthConsumer consumer = new OAuthConsumer(null, null, null, null);
> > > + consumer.setProperty(RSA_SHA1.PRIVATE_KEY, privateKeyObject);
> > > + OAuthAccessor accessor = new OAuthAccessor(consumer);
> > > + message.sign(accessor);
> > > + }
> > > +
> > > + /**
> > > + * Strip out any owner or viewer id passed by the client.
> > > + */
> > > + private List<Parameter> sanitize(List<Parameter> params) {
> > > + ArrayList<Parameter> list = new ArrayList<Parameter>();
> > > + for (Parameter p : params) {
> > > + if (allowParam(p.getKey())) {
> > > + list.add(p);
> > > + }
> > > + }
> > > + return list;
> > > + }
> > > +
> > > + private boolean allowParam(String paramName) {
> > > + String canonParamName = paramName.toLowerCase();
> > > + return (!(canonParamName.startsWith("oauth") ||
> > > + canonParamName.startsWith("xoauth") ||
> > > + canonParamName.startsWith("opensocial")) &&
> > > + ALLOWED_PARAM_NAME.matcher(canonParamName).matches());
> > > + }
> > > +}
> > >
> > > Added:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcherFactory.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcherFactory.java?rev=644123&view=auto
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcherFactory.java
> > (added)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcherFactory.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -0,0 +1,71 @@
> > > +/*
> > > + * 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.shindig.gadgets;
> > > +
> > > +import org.apache.shindig.util.InputStreamConsumer;
> > > +import org.apache.shindig.util.ResourceLoader;
> > > +
> > > +import com.google.inject.Inject;
> > > +import com.google.inject.name.Named;
> > > +
> > > +import java.io.IOException;
> > > +
> > > +/**
> > > + * Produces Signing content fetchers for input tokens.
> > > + */
> > > +public class SigningFetcherFactory {
> > > + private final String keyName;
> > > + private final String privateKey;
> > > +
> > > + /**
> > > + * Produces a signing fetcher that will sign requests and delegate
> > actual
> > > + * network retrieval to the {@code networkFetcher}
> > > + *
> > > + * @param networkFetcher The fetcher that will be doing actual work.
> > > + * @param token The gadget token used for extracting signing
> > parameters.
> > > + * @return The signing fetcher.
> > > + */
> > > + public RemoteContentFetcher getSigningFetcher(
> > > + RemoteContentFetcher networkFetcher, GadgetToken token) {
> > > + return SigningFetcher.makeFromB64PrivateKey(
> > > + networkFetcher, token, keyName, privateKey);
> > > + }
> > > +
> > > + /**
> > > + * @param keyName The key name (may be null) used in the signature.
> > > + * @param keyFile The file containing your private key for signing
> > requests.
> > > + */
> > > + @Inject
> > > + public SigningFetcherFactory(@Named("signing.key-name") String
> > keyName,
> > > + @Named("signing.key-file") String
> > keyFile) {
> > > + if (keyName == null || keyName.length() == 0) {
> > > + this.keyName = null;
> > > + } else {
> > > + this.keyName = keyName;
> > > + }
> > > + String privateKey = null;
> > > + try {
> > > + privateKey
> > > + =
> > InputStreamConsumer.readToString(ResourceLoader.open(keyFile));
> > > + } catch (IOException e) {
> > > + privateKey = "";
> > > + }
> > > + this.privateKey = privateKey;
> > > + }
> > > +}
> > >
> > > Modified:
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SyndicatorConfig.java
> > > URL:
> > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SyndicatorConfig.java?rev=644123&r1=644122&r2=644123&view=diff
> > >
> > ==============================================================================
> > > ---
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SyndicatorConfig.java
> > (original)
> > > +++
> > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SyndicatorConfig.java
> > Wed Apr 2 17:40:05 2008
> > > @@ -21,6 +21,9 @@
> > >
> > > import org.apache.shindig.util.ResourceLoader;
> > >
> > > +import com.google.inject.Inject;
> > > +import com.google.inject.name.Named;
> > > +
> > > import org.json.JSONArray;
> > > import org.json.JSONException;
> > > import org.json.JSONObject;
> > > @@ -45,7 +48,6 @@
> > > * your config that you actually want to change.
> > > */
> > > public class SyndicatorConfig {
> > > - public static final SyndicatorConfig EMPTY = new SyndicatorConfig();
> > > private final Map<String, JSONObject> config;
> > > public static final String DEFAULT_SYNDICATOR = "default";
> > > public static final String SYNDICATOR_KEY = "gadgets.syndicator";
> > > @@ -168,6 +170,7 @@
> > > private void loadResources(String[] files) throws GadgetException {
> > > try {
> > > for (String entry : files) {
> > > + logger.info("Reading syndicator config: " + entry);
> > > String content = ResourceLoader.getContent(entry);
> > > loadFromString(content);
> > > }
> > > @@ -212,8 +215,9 @@
> > > for (String field : fields) {
> > > Object existing = clone.opt(field);
> > > Object update = merge.get(field);
> > > - if (existing == null) {
> > > - // It's new custom config, not referenced in the prototype.
> > > + if (existing == null || update == null) {
> > > + // It's new custom config, not referenced in the prototype, or
> > > + // it's removing a pre-configured value.
> > > clone.put(field, update);
> > > } else {
> > > // Merge if object type is JSONObject.
> > > @@ -290,20 +294,13 @@
> > >
> > > /**
> > > * Creates a new, empty configuration.
> > > - *
> > > - * @param defaultSyndicator The default syndicators to load.
> > > */
> > > - public SyndicatorConfig(String defaultSyndicator) throws
> > GadgetException {
> > > + @Inject
> > > + public SyndicatorConfig(@Named("syndicators.default") String
> > syndicators)
> > > + throws GadgetException {
> > > config = new HashMap<String, JSONObject>();
> > > - if (defaultSyndicator != null) {
> > > - loadSyndicators(defaultSyndicator);
> > > + if (syndicators != null) {
> > > + loadSyndicators(syndicators);
> > > }
> > > - }
> > > -
> > > - /**
> > > - * Creates an unmodifiable configuration.
> > > - */
> > > - private SyndicatorConfig() {
> > > - config = Collections.emptyMap();
> > > }
> > > }
> > >
> > >
> > --
> > Santiago Gala
> > http://memojo.com/~sgala/blog/ <http://memojo.com/%7Esgala/blog/>
> >
> >
>
>
--
Santiago Gala
http://memojo.com/~sgala/blog/