Permalink
Browse files

Moved all herd handling from webdavcontentstore up to remotecontentstore

Otherwise completion is only done on output herd repos, since the webdav content
store is mostly used for output.
  • Loading branch information...
1 parent 6f0fb35 commit fbbe3a8e9f982d0ff94a32ce5dcf4ce88be17e92 @FroMage FroMage committed Sep 5, 2012
@@ -158,9 +158,4 @@ public OpenNode addContent(String label, InputStream content, ContentOptions opt
return null; // cannot add content
}
}
-
- @Override
- public boolean isHerd() {
- return false;
- }
}
@@ -17,14 +17,29 @@
package com.redhat.ceylon.cmr.impl;
import com.redhat.ceylon.cmr.api.Logger;
+import com.redhat.ceylon.cmr.api.ModuleQuery;
+import com.redhat.ceylon.cmr.api.ModuleResult;
+import com.redhat.ceylon.cmr.api.ModuleSearchResult;
+import com.redhat.ceylon.cmr.api.ModuleVersionDetails;
+import com.redhat.ceylon.cmr.api.ModuleVersionQuery;
+import com.redhat.ceylon.cmr.api.ModuleVersionResult;
+import com.redhat.ceylon.cmr.api.ModuleQuery.Type;
import com.redhat.ceylon.cmr.spi.ContentHandle;
import com.redhat.ceylon.cmr.spi.Node;
import com.redhat.ceylon.cmr.spi.OpenNode;
+import com.redhat.ceylon.cmr.util.WS;
+import com.redhat.ceylon.cmr.util.WS.Link;
+import com.redhat.ceylon.cmr.util.WS.Parser;
+import com.redhat.ceylon.cmr.util.WS.XMLHandler;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
import javax.xml.bind.DatatypeConverter;
@@ -35,9 +50,17 @@
*/
public abstract class URLContentStore extends AbstractRemoteContentStore {
+ public final static String HERD_COMPLETE_MODULES_REL = "http://modules.ceylon-lang.org/rel/complete-modules";
+ public final static String HERD_COMPLETE_VERSIONS_REL = "http://modules.ceylon-lang.org/rel/complete-versions";
+ public final static String HERD_SEARCH_MODULES_REL = "http://modules.ceylon-lang.org/rel/search-modules";
+
protected final String root;
protected String username;
protected String password;
+ private Boolean _isHerd = null;
+ private String herdCompleteModulesURL;
+ private String herdCompleteVersionsURL;
+ private String herdSearchModulesURL;
protected URLContentStore(String root, Logger log) {
super(log);
@@ -46,6 +69,58 @@ protected URLContentStore(String root, Logger log) {
this.root = root;
}
+ @Override
+ public boolean isHerd(){
+ if(_isHerd == null){
+ synchronized(this){
+ if(_isHerd == null){
+ _isHerd = testHerd();
+ }
+ }
+ }
+ return _isHerd;
+ }
+
+ private boolean testHerd() {
+ try{
+ URL rootURL = getURL("");
+ HttpURLConnection con = (HttpURLConnection) rootURL.openConnection();
+ try{
+ con.setRequestMethod("OPTIONS");
+ if(con.getResponseCode() != HttpURLConnection.HTTP_OK)
+ return false;
+ String herdVersion = con.getHeaderField("X-Herd-Version");
+ log.debug("Herd version: "+herdVersion);
+ boolean ret = herdVersion != null && !herdVersion.isEmpty();
+ if(ret){
+ collectHerdLinks(con);
+ }
+ return ret;
+ }finally{
+ con.disconnect();
+ }
+ }catch(Exception x){
+ log.debug("Failed to determine if remote host is a Herd repo: "+x.getMessage());
+ return false;
+ }
+ }
+
+ private void collectHerdLinks(HttpURLConnection con) {
+ // collect the links
+ try{
+ List<Link> links = WS.collectLinks(con);
+ herdCompleteModulesURL = WS.getLink(links, HERD_COMPLETE_MODULES_REL);
+ herdCompleteVersionsURL = WS.getLink(links, HERD_COMPLETE_VERSIONS_REL);
+ herdSearchModulesURL = WS.getLink(links, HERD_SEARCH_MODULES_REL);
+ log.debug("Got complete-modules link: " + herdCompleteModulesURL);
+ log.debug("Got complete-versions link: " + herdCompleteVersionsURL);
+ log.debug("Got search-modules link: " + herdSearchModulesURL);
+ }catch(Exception x){
+ log.debug("Failed to read links from Herd repo: "+x.getMessage());
+ }
+ }
+
+
public void setUsername(String username) {
this.username = username;
}
@@ -142,4 +217,166 @@ protected void addCredentials(HttpURLConnection conn) throws IOException {
}
}
}
+
+ @Override
+ public void completeModules(ModuleQuery lookup, final ModuleResult result) {
+ if(isHerd() && herdCompleteModulesURL != null){
+ // let's try Herd
+ try{
+ WS.getXML(herdCompleteModulesURL,
+ WS.params(WS.param("module", lookup.getName()),
+ WS.param("type", getHerdTypeParam(lookup.getType()))),
+ new XMLHandler(){
+ @Override
+ public void onOK(Parser p) {
+ parseCompleteModulesResponse(p, result);
+ }
+ });
+ }catch(Exception x){
+ log.info("Failed to get completion of modules from Herd: "+x.getMessage());
+ }
+ }
+ }
+
+ protected void parseCompleteModulesResponse(Parser p, ModuleResult result) {
+ p.moveToOpenTag("results");
+ while(p.moveToOptionalOpenTag("module")){
+ String module = p.contents();
+ result.addResult(module);
+ }
+ p.checkCloseTag();
+ }
+
+ private String getHerdTypeParam(Type type) {
+ switch(type){
+ case JS:
+ return "javascript";
+ case JVM:
+ return "jvm";
+ case SRC:
+ return "source";
+ default:
+ throw new RuntimeException("Missing enum case handling");
+ }
+ }
+
+ @Override
+ public void completeVersions(ModuleVersionQuery lookup, final ModuleVersionResult result) {
+ if(isHerd() && herdCompleteVersionsURL != null){
+ // let's try Herd
+ try{
+ WS.getXML(herdCompleteVersionsURL,
+ WS.params(WS.param("module", lookup.getName()),
+ WS.param("version", lookup.getVersion()),
+ WS.param("type", getHerdTypeParam(lookup.getType()))),
+ new XMLHandler(){
+ @Override
+ public void onOK(Parser p) {
+ parseCompleteVersionsResponse(p, result);
+ }
+ });
+ }catch(Exception x){
+ log.info("Failed to get completion of versions from Herd: "+x.getMessage());
+ }
+ }
+ }
+
+ protected void parseCompleteVersionsResponse(Parser p, ModuleVersionResult result) {
+ List<String> authors = new LinkedList<String>();
+ p.moveToOpenTag("results");
+
+ while(p.moveToOptionalOpenTag("module-version")){
+ String module = null, version = null, doc = null, license = null;
+ authors.clear();
+
+ while(p.moveToOptionalOpenTag()){
+ if(p.isOpenTag("module")){
+ // ignored
+ module = p.contents();
+ }else if(p.isOpenTag("version")){
+ version = p.contents();
+ }else if(p.isOpenTag("doc")){
+ doc = p.contents();
+ }else if(p.isOpenTag("license")){
+ license = p.contents();
+ }else if(p.isOpenTag("authors")){
+ authors.add(p.contents());
+ }else{
+ throw new RuntimeException("Unknown tag: "+p.tagName());
+ }
+ }
+ if(version == null || version.isEmpty())
+ throw new RuntimeException("Missing required version");
+ ModuleVersionDetails newVersion = result.addVersion(version);
+ if(newVersion != null){
+ if(doc != null && !doc.isEmpty())
+ newVersion.setDoc(doc);
+ if(license != null && !license.isEmpty())
+ newVersion.setLicense(license);
+ if(!authors.isEmpty())
+ newVersion.getAuthors().addAll(authors);
+ }
+ p.checkCloseTag();
+ }
+ p.checkCloseTag();
+ }
+
+ @Override
+ public void searchModules(ModuleQuery query, final ModuleSearchResult result) {
+ if(isHerd() && herdSearchModulesURL != null){
+ // let's try Herd
+ try{
+ WS.getXML(herdSearchModulesURL,
+ WS.params(WS.param("query", query.getName()),
+ WS.param("type", getHerdTypeParam(query.getType())),
+ WS.param("start", query.getStart()),
+ WS.param("count", query.getCount())),
+ new XMLHandler(){
+ @Override
+ public void onOK(Parser p) {
+ parseSearchModulesResponse(p, result);
+ }
+ });
+ }catch(Exception x){
+ log.info("Failed to search modules from Herd: "+x.getMessage());
+ }
+ }
+ }
+
+ protected void parseSearchModulesResponse(Parser p, ModuleSearchResult result) {
+ SortedSet<String> authors = new TreeSet<String>();
+ SortedSet<String> versions = new TreeSet<String>();
+
+ p.moveToOpenTag("results");
+ while(p.moveToOptionalOpenTag("module")){
+ String module = null, doc = null, license = null;
+ authors.clear();
+ versions.clear();
+
+ while(p.moveToOptionalOpenTag()){
+ if(p.isOpenTag("name")){
+ module = p.contents();
+ }else if(p.isOpenTag("versions")){
+ versions.add(p.contents());
+ }else if(p.isOpenTag("doc")){
+ doc = p.contents();
+ }else if(p.isOpenTag("license")){
+ license = p.contents();
+ }else if(p.isOpenTag("authors")){
+ authors.add(p.contents());
+ }else{
+ throw new RuntimeException("Unknown tag: "+p.tagName());
+ }
+ }
+ if(module == null || module.isEmpty())
+ throw new RuntimeException("Missing required module name");
+ if(versions.isEmpty()){
+ log.debug("Ignoring result for " + module + " because it doesn't have a single version");
+ }else{
+ result.addResult(module, doc, license, authors, versions);
+ }
+ p.checkCloseTag();
+ }
+ p.checkCloseTag();
+ }
}
Oops, something went wrong.

0 comments on commit fbbe3a8

Please sign in to comment.