2008/3/29, Aaron Cheung <[EMAIL PROTECTED]>:
> That would be real nice.. have been under the impression that Shindig
> requires Java,
> perhaps due to historical impression from day 1 of Shindig... Thanks Dan..
> cheers!
Aaron, another trick is that you can hang some code down at the end of
the Java maven-jetty conundrum, and call any other webservice you
have.
example, to provide a person service
1) In
shindig/java/gadgets/src/main/java/org/apache/shindig/social/opensocial/OpenSocialDataHandler.java
you change the basic service:
//import org.apache.shindig.social.samplecontainer.BasicPeopleService;
import org.apache.shindig.social.RemoteHttpContainer.BasicPeopleService;
2) create a new directory
j.../java/org/apache/shindig/social/RemoteHttpContainer
3) install a BasicPeople Service there. Actually I have an example
with two files,
BasicPeopleService.java and XmlFileFetcher.java, because it is
inspired in the other sample, so BasicPeopleService is still the same
file except the headers
I am attaching the files as example, but note that the friend list is
not implemented (I will do it tomorrow). I do not know if this idea
could qualify for a patch, at least in order to provide a different
example of FileFetcher (non persistent).
Alejandro
package org.apache.shindig.social.RemoteHttpContainer;
import org.apache.shindig.gadgets.BasicRemoteContentFetcher;
import org.apache.shindig.gadgets.RemoteContent;
import org.apache.shindig.gadgets.RemoteContentFetcher;
import org.apache.shindig.gadgets.RemoteContentRequest;
import org.apache.shindig.social.opensocial.model.Activity;
import org.apache.shindig.social.opensocial.model.MediaItem;
import org.apache.shindig.social.opensocial.model.Name;
import org.apache.shindig.social.opensocial.model.Person;
import org.apache.shindig.social.opensocial.model.Address;
import org.apache.shindig.social.opensocial.model.Phone;
import org.apache.shindig.social.opensocial.model.Enum;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Alejandro Rivero <[EMAIL PROTECTED]>
* code "inspired" in the basic container example by Cassandra Doll
*/
public class XmlFileFetcher {
private static final String DEFAULT_STATE_URL
= "http://registro.ibercivis.es/boincopensocial/";
private Document document;
private Person SinglePerson;
private List<String> PersonFriendId;
private URI stateFile;
private Document fetchStateDocument(String clavePersona) {
try {
stateFile = new URI(DEFAULT_STATE_URL+clavePersona);
} catch (URISyntaxException e) {
throw new RuntimeException(
"The default state file could not be fetched. ", e);
}
RemoteContentFetcher fetcher = new BasicRemoteContentFetcher(1024 * 1024);
RemoteContent xml = fetcher.fetch(new RemoteContentRequest(stateFile));
InputSource is = new InputSource(new StringReader(
xml.getResponseAsString()));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // never forget this!
String errorMessage = "The state file " + stateFile
+ " could not be fetched and parsed.";
try {
document = factory.newDocumentBuilder().parse(is);
return document;
} catch (SAXException e) {
throw new RuntimeException(errorMessage, e);
} catch (IOException e) {
throw new RuntimeException(errorMessage, e);
} catch (ParserConfigurationException e) {
throw new RuntimeException(errorMessage, e);
}
}
//punto de entrada para la lista de amigos de una persona
public List<String> getFriends(String clavePersona) {
Element root = fetchStateDocument("people/"+clavePersona+"/@friends").getDocumentElement();
// para otro dia setupFriendsInXmlTag(root, "people");
return PersonFriendId;
}
// punto de entrada para los datos fijos de una persona
public Person getOnePerson(String clavePersona) {
Element root = fetchStateDocument("people/"+clavePersona+"/@self").getDocumentElement();
setupPeopleInXmlTag(root, "people");
return SinglePerson;
}
// root is en Element, but it is a Document too, it can be typecasted I hope
private void setupPeopleInXmlTag(Element root, String tagName) {
// TODO: Use the opensource Collections library
try {
XPath xpath = XPathFactory.newInstance( XPathFactory.DEFAULT_OBJECT_MODEL_URI ).newXPath();
String name=xpath.evaluate("/respuesta/people/person/name", document);
String id=xpath.evaluate("/respuesta/people/person/authenticator", document);
SinglePerson = new Person(id, new Name(name));
//pasamos de momento el email como unstructured, luego pasaremos ahi la de verdad
//y el email en su sitio
Address direccion=new Address(xpath.evaluate("/respuesta/people/person/email_addr", document));
direccion.setCountry(xpath.evaluate("/respuesta/people/person/country", document));
direccion.setLocality(xpath.evaluate("/respuesta/people/person/postal_code", document));
//problema: longitud y latitud son Float
//direccion.setLatitude xpath.evaluate("/respuesta/people/person/latitud", document)
//direccion.setLongitude xpath.evaluate("/respuesta/people/person/longitud", document)
SinglePerson.setCurrentLocation(direccion);
if ("1"==xpath.evaluate("/respuesta/people/person/has_profile", document)){
SinglePerson.setProfileUrl("http://registro.ibercivis.es/");
}
} catch (XPathFactoryConfigurationException e) { throw new RuntimeException("brrr", e); }
catch (XPathExpressionException e) { throw new RuntimeException("brrr", e); }
}
}
/*
* 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.social.RemoteHttpContainer;
import org.apache.shindig.social.ResponseItem;
import org.apache.shindig.social.opensocial.PeopleService;
import org.apache.shindig.social.opensocial.model.IdSpec;
import org.apache.shindig.social.opensocial.model.Person;
import org.apache.shindig.social.opensocial.model.ApiCollection;
import org.apache.shindig.gadgets.GadgetToken;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Collections;
import java.util.Comparator;
public class BasicPeopleService implements PeopleService {
private static final Comparator<Person> NAME_COMPARATOR
= new Comparator<Person>() {
public int compare(Person person, Person person1) {
String name = person.getName().getUnstructured();
String name1 = person1.getName().getUnstructured();
return name.compareTo(name1);
}
};
public ResponseItem<ApiCollection<Person>> getPeople(List<String> ids,
SortOrder sortOrder, FilterType filter, int first, int max,
Set<String> profileDetails, GadgetToken token) {
List<Person> people = new ArrayList<Person>();
for (String id : ids) {
XmlFileFetcher fetcher= new XmlFileFetcher();
Person person = fetcher.getOnePerson(id);
if (person != null) {
if (id.equals(token.getViewerId())) {
person.setIsViewer(true);
}
if (id.equals(token.getOwnerId())) {
person.setIsOwner(true);
}
people.add(person);
}
}
// We can pretend that by default the people are in top friends order
if (sortOrder.equals(SortOrder.name)) {
Collections.sort(people, NAME_COMPARATOR);
}
// TODO: The samplecontainer doesn't really have the concept of HAS_APP so
// we can't support any filters yet. We should fix this.
int totalSize = people.size();
int last = first + max;
people = people.subList(first, Math.min(last, totalSize));
ApiCollection<Person> collection = new ApiCollection<Person>(people, first,
totalSize);
return new ResponseItem<ApiCollection<Person>>(collection);
}
public List<String> getIds(IdSpec idSpec, GadgetToken token)
throws JSONException {
XmlFileFetcher fetcher= new XmlFileFetcher();
List<String> ids = new ArrayList<String>();
switch(idSpec.getType()) {
case OWNER:
ids.add(token.getOwnerId());
break;
case VIEWER:
ids.add(token.getViewerId());
break;
case OWNER_FRIENDS:
ids.addAll(fetcher.getFriends(token.getOwnerId()));
//replaces ids.addAll(friendIds.get(token.getOwnerId()));
break;
case VIEWER_FRIENDS:
ids.addAll(fetcher.getFriends(token.getOwnerId()));
//ids.addAll(friendIds.get(token.getViewerId()));
break;
case USER_IDS:
ids.addAll(idSpec.fetchUserIds());
break;
}
return ids;
}
}