2c1edfc333aea4ff30046df5a89f9a150ecf5c78 kent Thu Oct 28 14:51:11 2010 -0700 Adding trackHubAddNamePrefix to help give hubs their own name space within cart. diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c index ddd01de..17f2dd0 100644 --- src/hg/lib/trackHub.c +++ src/hg/lib/trackHub.c @@ -177,30 +177,43 @@ *pList = NULL; } static char *requiredSetting(struct trackHub *hub, struct trackHubGenome *genome, struct trackDb *tdb, char *setting) /* Fetch setting or give an error message, a little more specific than the * error message from trackDbRequiredSetting(). */ { char *val = trackDbSetting(tdb, setting); if (val == NULL) errAbort("Missing required %s setting in hub %s genome %s track %s", setting, hub->url, genome->name, tdb->track); return val; } +static void expandBigDataUrl(struct trackHub *hub, struct trackHubGenome *genome, + struct trackDb *tdb) +/* Expand bigDataUrls so that no longer relative to genome->trackDbFile */ +{ +struct hashEl *hel = hashLookup(tdb->settingsHash, "bigDataUrl"); +if (hel != NULL) + { + char *oldVal = hel->val; + hel->val = trackHubRelativeUrl(genome->trackDbFile, oldVal); + freeMem(oldVal); + } +} + static void checkTagsLegal(struct trackHub *hub, struct trackHubGenome *genome, struct trackDb *tdb) /* Make sure that tdb has all the required tags and is of a supported type. */ { /* Check for existence of fields required in all tracks */ requiredSetting(hub, genome, tdb, "shortLabel"); requiredSetting(hub, genome, tdb, "longLabel"); /* Further checks depend whether it is a container. */ if (tdb->subtracks != NULL) { if (trackDbSetting(tdb, "compositeTrack")) { } else if (trackDbSetting(tdb, "container")) @@ -234,48 +247,90 @@ struct trackHubGenome *trackHubFindGenome(struct trackHub *hub, char *genomeName) /* Return trackHubGenome of given name associated with hub. Return NULL if no * such genome. */ { return hashFindVal(hub->genomeHash, genomeName); } struct trackDb *trackHubTracksForGenome(struct trackHub *hub, struct trackHubGenome *genome) /* Get list of tracks associated with genome. Check that it only is composed of legal * types. Do a few other quick checks to catch errors early. */ { struct lineFile *lf = udcWrapShortLineFile(genome->trackDbFile, NULL, 16*1024*1024); struct trackDb *tdbList = trackDbFromOpenRa(lf); lineFileClose(&lf); +/* Make bigDataUrls more absolute rather than relative to genome.ra dir */ +struct trackDb *tdb; +for (tdb = tdbList; tdb != NULL; tdb = tdb->next) + expandBigDataUrl(hub, genome, tdb); + /* Connect up subtracks and parents. Note this loop does not actually move tracks * from list to parent subtracks, it just uses the field as a marker. Just do this * so when doing error checking can distinguish between container tracks and others. * This does have the pleasant side effect of making good error messages for * non-existant parents. */ -struct trackDb *tdb; struct hash *hash = hashNew(0); for (tdb = tdbList; tdb != NULL; tdb = tdb->next) hashAdd(hash, tdb->track, tdb); for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { char *parentName = trackDbLocalSetting(tdb, "parent"); if (parentName != NULL) { struct trackDb *parent = hashFindVal(hash, parentName); if (parent == NULL) errAbort("Parent %s of track %s doesn't exist in hub %s genome %s", parentName, tdb->track, hub->url, genome->name); tdb->parent = parent; parent->subtracks = tdb; } } hashFree(&hash); /* Loop through list checking tags and removing ad-hoc use of parent and subtracks tags. */ for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { checkTagsLegal(hub, genome, tdb); tdb->parent = tdb->subtracks = NULL; } return tdbList; } +static void reprefixString(char **pString, char *prefix) +/* Replace *pString with prefix + *pString, freeing + * whatever was in *pString before. */ +{ +char *oldName = *pString; +*pString = catTwoStrings(prefix, oldName); +freeMem(oldName); +} + +static void addPrefixToSetting(struct hash *settings, char *key, char *prefix) +/* Given a settings hash, which is string valued. Old values will be freed. */ +{ +struct hashEl *hel = hashLookup(settings, key); +if (hel != NULL) + reprefixString((char **)&hel->val, prefix); +} + +static void trackDbListAddNamePrefix(struct trackDb *tdbList, char *prefix) +/* Surgically alter tdbList so that it works as if every track was + * renamed so as to add a prefix to it's name. */ +{ +struct trackDb *tdb; +for (tdb = tdbList; tdb != NULL; tdb = tdb->next) + { + addPrefixToSetting(tdb->settingsHash, "track", prefix); + addPrefixToSetting(tdb->settingsHash, "parent", prefix); + reprefixString(&tdb->track, prefix); + } +} + +void trackHubAddNamePrefix(char *hubName, struct trackDb *tdbList) +/* For a hub named "xyz" add the prefix "hub_xyz_" to each track and parent field. */ +{ +char namePrefix[PATH_LEN]; +safef(namePrefix, sizeof(namePrefix), "hub_%s_", hubName); +trackDbListAddNamePrefix(tdbList, namePrefix); +} +