Skip to content
Commits on Source (7)
......@@ -2,3 +2,4 @@
.idea/workspace.xml
*.jar
igv.sh
/out/
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 Broad Institute
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<project name="IGV" default="all" basedir=".">
......
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 Broad Institute
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<project name="macrodefs">
......
igv (2.4.4+dfsg-1) UNRELEASED; urgency=medium
igv (2.4.6+dfsg-1) unstable; urgency=medium
[ Steffen Moeller ]
* debian/upstream/metadata:
......@@ -13,8 +13,9 @@ igv (2.4.4+dfsg-1) UNRELEASED; urgency=medium
* Standards-Version: 4.1.3
* New Build-Depends: openjfx
* Drop libconcurrent-java from Build-Depends
* debhelper 11
-- Andreas Tille <tille@debian.org> Tue, 05 Dec 2017 09:49:13 +0100
-- Andreas Tille <tille@debian.org> Mon, 22 Jan 2018 09:52:36 +0100
igv (2.3.90+dfsg-1) unstable; urgency=medium
......
......@@ -8,7 +8,7 @@ Priority: optional
Build-Depends: default-jdk,
ant,
junit4,
debhelper (>= 10),
debhelper (>= 11~),
libbatik-java,
libcofoja-java,
libcommons-logging-java,
......
......@@ -3,7 +3,7 @@ Origin: vendor
Forwarded: no
--- a/build.xml
+++ b/build.xml
@@ -17,7 +17,8 @@
@@ -31,7 +31,8 @@
<!-- Source and lib directories -->
<property name="src.dir" value="${basedir}/src/"/>
......@@ -13,7 +13,7 @@ Forwarded: no
<property name="testsrc.dir" value="${basedir}/test/src"/>
<property name="testlib.dir" value="${basedir}/test/lib"/>
@@ -38,13 +39,52 @@
@@ -52,13 +53,52 @@
<property name="javac.nowarn" value="off"/>
......@@ -68,7 +68,7 @@ Forwarded: no
<exclude name="appbundler*.jar"/>
</fileset>
</path>
@@ -75,13 +115,13 @@
@@ -89,13 +129,13 @@
<patternset>
<include name="**/*"/>
<exclude name="META-INF/**"/>
......@@ -83,7 +83,7 @@ Forwarded: no
<exclude name="**/${goby-io-finame}"/>
<exclude name="**/*AppleJavaExtensions.jar"/>
</fileset>
@@ -106,6 +146,15 @@
@@ -120,6 +160,15 @@
<exclude name="**/manifest.mf"/>
</fileset>
</copy>
......@@ -99,7 +99,7 @@ Forwarded: no
<antcall target="prepare"/>
<write_version targetFile="${resource.dir}about.properties"/>
@@ -130,6 +179,11 @@
@@ -144,6 +193,11 @@
srcdir="${src.dir}" debug="on" destdir="${tmp.dir}" encoding="${java.encoding}"
target="${javac.target}" source="${javac.target}" nowarn="${javac.nowarn}">
<classpath refid="@jars"/>
......@@ -111,7 +111,7 @@ Forwarded: no
</javac>
<!--
<copy todir="${tmp.dir}/META-INF/services" overwrite="true">
@@ -161,7 +215,8 @@
@@ -175,7 +229,8 @@
<attribute name="includedFileset"/>
<sequential>
......@@ -121,7 +121,7 @@ Forwarded: no
<fileset refid="@{includedFileset}"/>
<manifest>
@@ -183,8 +238,8 @@
@@ -197,8 +252,8 @@
</manifest>
</jar>
......@@ -132,7 +132,7 @@ Forwarded: no
<delete dir="${tmp.dir}"/>
<delete dir="${testtmp.dir}"/>
</sequential>
@@ -195,7 +250,7 @@
@@ -209,7 +264,7 @@
<fileset dir="${tmp.dir}" id="files"/>
<pathconvert property="class-path" pathsep=" " dirsep="/" refid="@jars">
......@@ -141,7 +141,7 @@ Forwarded: no
</pathconvert>
<build includedFileset="files"/>
@@ -208,7 +263,7 @@
@@ -222,7 +277,7 @@
<root classname="${main-class}"/>
</classfileset>
......
{
"id": "hg38",
"ucscID": "hg38",
"name": "Human (hg38)",
"fastaURL": "http://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa",
"indexURL": "http://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai",
"cytobandURL": "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/cytoBandIdeo.txt.gz",
"aliasURL": "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/hg38/hg38_alias.tab",
"annotations": [
{
"name": "Refseq Genes",
"url": "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/refGene.txt.gz",
"indexed": false
}
]
}
https://s3.amazonaws.com/igv.broadinstitute.org/annotations/WS235/WS235_annotations.xml
<?xml version="1.0"?>
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 Broad Institute
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<project name="igvtools" basedir="../." default="deploy">
......
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 Broad Institute
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<project name="IGV" default="build" basedir="../.">
......
......@@ -335,7 +335,7 @@ public class CommandExecutor {
}
}
private String setSleepInterval(String param1) {
public String setSleepInterval(String param1) {
try {
sleepInterval = Integer.parseInt(param1.trim());
return "OK";
......
......@@ -40,6 +40,7 @@ import org.broad.igv.feature.Chromosome;
import org.broad.igv.feature.Cytoband;
import org.broad.igv.track.FeatureTrack;
import org.broad.igv.ui.panel.ReferenceFrame;
import org.broad.igv.util.ResourceLocator;
import java.io.*;
import java.util.*;
......@@ -67,6 +68,7 @@ public class Genome {
private String species;
private String ucscID;
private GenomeDescriptor descriptor; // Can be null
private ArrayList<ResourceLocator> annotationResources;
public Genome(String id, String displayName, Sequence sequence, boolean chromosOrdered, GenomeDescriptor descriptor) {
......@@ -601,4 +603,12 @@ public class Genome {
public boolean sequenceIsLoaded(ReferenceFrame frame) {
return sequence.isLoaded(frame);
}
public void setAnnotationResources(ArrayList<ResourceLocator> annotationResources) {
this.annotationResources = annotationResources;
}
public ArrayList<ResourceLocator> getAnnotationResources() {
return annotationResources;
}
}
......@@ -43,7 +43,6 @@ import java.io.InputStream;
public abstract class GenomeDescriptor {
private String name;
private boolean chrNamesAltered;
private String id;
protected String cytoBandFileName;
protected String geneFileName;
......@@ -55,11 +54,9 @@ public abstract class GenomeDescriptor {
private boolean hasCustomSequencePath;
private boolean chromosomesAreOrdered = false;
private boolean fasta = false;
private boolean fastaDirectory = false;
private String [] fastaFileNames;
public GenomeDescriptor(String name,
boolean chrNamesAltered,
String id,
String cytoBandFileName,
String geneFileName,
......@@ -70,9 +67,7 @@ public abstract class GenomeDescriptor {
String compressedSequencePath,
boolean chromosomesAreOrdered,
boolean fasta,
boolean fastaDirectory,
String fastaFileNameString) {
this.chrNamesAltered = chrNamesAltered;
this.name = name;
this.id = id;
this.cytoBandFileName = cytoBandFileName;
......@@ -84,7 +79,6 @@ public abstract class GenomeDescriptor {
this.compressedSequencePath = compressedSequencePath;
this.chromosomesAreOrdered = chromosomesAreOrdered;
this.fasta = fasta;
this.fastaDirectory = fastaDirectory;
if(fastaFileNameString != null) {
fastaFileNames = fastaFileNameString.split(",");
......@@ -109,8 +103,6 @@ public abstract class GenomeDescriptor {
return id;
}
// Used to determine feature file type, really only extension is needed
public String getGeneFileName() {
return geneFileName;
}
......@@ -123,12 +115,6 @@ public abstract class GenomeDescriptor {
return fastaFileNames;
}
public abstract InputStream getCytoBandStream() throws IOException;
public abstract InputStream getGeneStream() throws IOException;
public abstract InputStream getChrAliasStream() throws IOException;
public String getSequencePath() {
return compressedSequencePath == null ? sequencePath : compressedSequencePath;
}
......@@ -165,4 +151,10 @@ public abstract class GenomeDescriptor {
return hasCustomSequencePath;
}
public abstract InputStream getCytoBandStream() throws IOException;
public abstract InputStream getGeneStream() throws IOException;
public abstract InputStream getChrAliasStream() throws IOException;
}
......@@ -34,6 +34,10 @@
package org.broad.igv.feature.genome;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.log4j.Logger;
import org.broad.igv.DirectoryManager;
import org.broad.igv.Globals;
......@@ -51,8 +55,10 @@ import org.broad.igv.track.*;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.commandbar.GenomeListManager;
import org.broad.igv.ui.panel.FrameManager;
import org.broad.igv.ui.util.*;
import org.broad.igv.ui.util.MessageUtils;
import org.broad.igv.ui.util.ProgressBar;
import org.broad.igv.ui.util.ProgressMonitor;
import org.broad.igv.ui.util.UIUtilities;
import org.broad.igv.ui.util.download.Downloader;
import org.broad.igv.util.*;
......@@ -101,21 +107,10 @@ public class GenomeManager {
private GenomeListManager genomeListManager;
// public static String getUserDefinedGenomeListFile() {
// if (Globals.isTesting()) {
// return TEST_USER_DEFINED_GENOME_LIST_FILE;
// } else {
// return ACT_USER_DEFINED_GENOME_LIST_FILE;
// }
//
// }
private static GenomeManager theInstance;
private Genome currentGenome;
boolean serverGenomeListUnreachable = false;
private Map<String, File> localSequenceMap;
/**
......@@ -149,9 +144,6 @@ public class GenomeManager {
}
}
public boolean isServerGenomeListUnreachable() {
return serverGenomeListUnreachable;
}
public void loadGenomeById(String genomeId) throws IOException {
......@@ -214,7 +206,11 @@ public class GenomeManager {
} else if (genomePath.endsWith(".chrom.sizes")) {
altGenomePath = genomePath;
newGenome = loadChromSizes(genomePath);
} else if (genomePath.endsWith(".json")) {
altGenomePath = genomePath;
newGenome = loadJsonFile(genomePath);
} else {
// Assume a fasta file
altGenomePath = genomePath;
if (genomePath.endsWith(Globals.GZIP_FILE_EXTENSION)) {
......@@ -262,8 +258,13 @@ public class GenomeManager {
setCurrentGenome(newGenome);
if (IGV.hasInstance()) {
FeatureTrack geneFeatureTrack = newGenome.getGeneTrack();
FeatureTrack geneFeatureTrack = newGenome.getGeneTrack(); // Can be null
IGV.getInstance().setGenomeTracks(geneFeatureTrack);
List<ResourceLocator> resources = newGenome.getAnnotationResources();
if (resources != null) {
IGV.getInstance().loadResources(resources);
}
}
......@@ -384,6 +385,55 @@ public class GenomeManager {
return newGenome;
}
private Genome loadJsonFile(String genomePath) throws IOException {
Genome newGenome = null;
BufferedReader reader = ParsingUtils.openBufferedReader(genomePath);
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(reader).getAsJsonObject();
String id = json.get("id").getAsString();
String name = json.get("name").getAsString();
String fastaPath = json.get("fastaURL").getAsString();
JsonElement indexPathObject = json.get("indexURL");
String indexPath = indexPathObject == null ? null : indexPathObject.getAsString();
FastaIndexedSequence sequence = fastaPath.endsWith(".gz") ?
new FastaBlockCompressedSequence(fastaPath, indexPath) :
new FastaIndexedSequence(fastaPath, indexPath);
ArrayList<ResourceLocator> tracks = new ArrayList<>();
JsonArray annotations = json.getAsJsonArray("annotations");
if (annotations != null) {
annotations.forEach((JsonElement jsonElement) -> {
JsonObject obj = jsonElement.getAsJsonObject();
String trackPath = obj.get("url").getAsString();
JsonElement trackName = obj.get("name");
JsonElement trackIndexPath = obj.get("indexURL");
JsonElement indexed = obj.get("indexed");
JsonElement aliasURL = obj.get("aliasURL");
ResourceLocator res = new ResourceLocator(trackPath);
if (trackName != null) res.setName(trackName.getAsString());
if (trackIndexPath != null) res.setIndexPath(trackIndexPath.getAsString());
if (indexed != null) res.setIndexed(indexed.getAsBoolean());
tracks.add(res);
});
}
newGenome = new Genome(id, name, sequence, true);
newGenome.setAnnotationResources(tracks);
// TODO -- set aliases
return newGenome;
}
private Collection<Collection<String>> loadChrAliases(String path) {
// String id = genome.getId();
......@@ -720,7 +770,6 @@ public class GenomeManager {
// The new descriptor
genomeDescriptor = new GenomeZipDescriptor(
properties.getProperty(GENOME_ARCHIVE_NAME_KEY),
chrNamesAltered,
properties.getProperty(GENOME_ARCHIVE_ID_KEY),
cytobandZipEntryName,
geneFileName,
......@@ -733,7 +782,6 @@ public class GenomeManager {
zipEntries,
chromosomesAreOrdered,
fasta,
fastaDirectory,
fastaFileNameString);
if (url != null) {
......
......@@ -43,7 +43,6 @@ public class GenomeZipDescriptor extends GenomeDescriptor {
private ZipFile genomeZipFile;
public GenomeZipDescriptor(String name,
boolean chrNamesAltered,
String id,
String cytoBandFileName,
String geneFileName,
......@@ -56,12 +55,11 @@ public class GenomeZipDescriptor extends GenomeDescriptor {
Map<String, ZipEntry> zipEntries,
boolean chromosomesAreOrdered,
boolean fasta,
boolean fastaDirectory,
String fastaFileNameString) {
super(name, chrNamesAltered, id, cytoBandFileName, geneFileName, chrAliasFileName, geneTrackName,
super(name, id, cytoBandFileName, geneFileName, chrAliasFileName, geneTrackName,
sequenceLocation, hasCustomSequenceLocation, compressedSequencePath,
chromosomesAreOrdered, fasta, fastaDirectory, fastaFileNameString);
chromosomesAreOrdered, fasta, fastaFileNameString);
this.zipEntries = zipEntries;
this.genomeZipFile = genomeZipFile;
......
......@@ -7,25 +7,31 @@ import org.broad.igv.util.LittleEndianInputStream;
import org.broad.igv.util.ParsingUtils;
import org.broad.igv.util.stream.IGVSeekableStreamFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by jrobinso on 6/23/17.
*/
public class FastaBlockCompressedSequence extends FastaIndexedSequence {
Mapping [] gziMappings;
Mapping[] gziMappings;
Mapping zeroMapping = new Mapping(0, 0);
public FastaBlockCompressedSequence(String path) throws IOException {
super(path);
String gziPath = path + ".gzi";
this(path, null);
}
public FastaBlockCompressedSequence(String path, String indexPath) throws IOException {
super(path);
readGziMappings(gziPath);
if(indexPath == null) indexPath = path + ".gzi";
readGziMappings(indexPath);
}
@Override
......@@ -44,7 +50,7 @@ public class FastaBlockCompressedSequence extends FastaIndexedSequence {
try {
int nBytes = (int) (posEnd - posStart);
int bufferSize = Math.max(512000, nBytes/8);
int bufferSize = Math.max(512000, nBytes / 8);
ss = new SeekableBufferedStream(IGVSeekableStreamFactory.getInstance().getStreamFor(path), bufferSize);
......@@ -66,16 +72,15 @@ public class FastaBlockCompressedSequence extends FastaIndexedSequence {
protected Mapping findBlockContaining(long uoffset) {
int ilo = 0, ihi = gziMappings.length - 1;
while ( ilo<=ihi )
{
int i = (ilo+ihi) / 2;
while (ilo <= ihi) {
int i = (ilo + ihi) / 2;
Mapping mapping = gziMappings[i];
if ( uoffset < mapping.uncompressedOffset ) ihi = i - 1;
else if ( uoffset >= mapping.uncompressedOffset ) ilo = i + 1;
if (uoffset < mapping.uncompressedOffset) ihi = i - 1;
else if (uoffset >= mapping.uncompressedOffset) ilo = i + 1;
else break;
}
return ilo == 0 ? zeroMapping : gziMappings[ilo-1];
return ilo == 0 ? zeroMapping : gziMappings[ilo - 1];
}
......@@ -99,13 +104,13 @@ public class FastaBlockCompressedSequence extends FastaIndexedSequence {
private void readFully(byte[] b, InputStream is) throws IOException {
int len = b.length;
if(len < 0) {
if (len < 0) {
throw new IndexOutOfBoundsException();
} else {
int count;
for(int n = 0; n < len; n += count) {
for (int n = 0; n < len; n += count) {
count = is.read(b, n, len - n);
if(count < 0) {
if (count < 0) {
throw new EOFException();
}
}
......
......@@ -25,12 +25,10 @@
package org.broad.igv.feature.genome.fasta;
import htsjdk.samtools.seekablestream.SeekableBufferedStream;
import htsjdk.samtools.seekablestream.SeekableStream;
import org.apache.log4j.Logger;
import org.broad.igv.feature.genome.Sequence;
import org.broad.igv.util.FileUtils;
import org.broad.igv.util.HttpUtils;
import org.broad.igv.util.ParsingUtils;
import org.broad.igv.util.stream.IGVSeekableStreamFactory;
......@@ -56,11 +54,15 @@ public class FastaIndexedSequence implements Sequence {
private final ArrayList<String> chromoNamesList;
public FastaIndexedSequence(String path) throws IOException {
this(path, null);
}
public FastaIndexedSequence(String path, String indexPath) throws IOException {
this.path = path;
contentLength = ParsingUtils.getContentLength(path);
String indexPath = path + ".fai";
if (indexPath == null) indexPath = path + ".fai";
index = new FastaIndex(indexPath);
chromoNamesList = new ArrayList<>(index.getSequenceNames());
......@@ -95,6 +97,7 @@ public class FastaIndexedSequence implements Sequence {
FastaIndex.FastaSequenceIndexEntry idxEntry = index.getIndexEntry(chr);
if (idxEntry == null) {
log.info("No fasta sequence entry for: " + chr);
return null;
}
......@@ -149,8 +152,7 @@ public class FastaIndexedSequence implements Sequence {
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
log.error("Error loading sequence " + chr + ":" + qstart + "-" + qend, e);
return null;
}
}
......@@ -171,7 +173,7 @@ public class FastaIndexedSequence implements Sequence {
SeekableStream ss = null;
try {
ss = IGVSeekableStreamFactory.getInstance().getStreamFor(path);
ss = IGVSeekableStreamFactory.getInstance().getStreamFor(path);
int nBytes = (int) (posEnd - posStart);
byte[] bytes = new byte[nBytes];
ss.seek(posStart);
......
......@@ -37,12 +37,17 @@ import org.broad.igv.util.FileUtils;
import org.broad.igv.util.HttpUtils;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.prefs.Preferences;
/**
......@@ -66,7 +71,7 @@ public class OAuthUtils {
private static final String PROPERTIES_URL = "https://igvdata.broadinstitute.org/app/oauth_native.json";
private String genomicsScope = "https://www.googleapis.com/auth/genomics";
private String gsScope = "https://www.googleapis.com/auth/devstorage.read_write";
private String profileScope = "https://www.googleapis.com/auth/userinfo.profile";
private String emailScope = "https://www.googleapis.com/auth/userinfo.email";
private String state = "%2Fprofile";
private String redirectURI = "http%3A%2F%2Flocalhost%3A60151%2FoauthCallback";
private String oobURI = "urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob";
......@@ -84,19 +89,23 @@ public class OAuthUtils {
private static OAuthUtils theInstance;
private String currentUserName;
private String currentUserEmail;
private String currentUserID;
// dwm08
// by default this is the google scope
private String scope = genomicsScope + "%20" + gsScope + "%20" + profileScope;
private String scope = genomicsScope + "%20" + gsScope + "%20" + emailScope;
// Construct OAuthUtils earcly so Google menu can be updated to the
// Construct OAuthUtils earcly so Google menu can be updated to the
// correct oauth provider. dwm08
static {
if (theInstance == null) {
if (theInstance == null) {
theInstance = new OAuthUtils();
}
}
public static synchronized OAuthUtils getInstance() {
if (theInstance == null) {
......@@ -169,7 +178,7 @@ public class OAuthUtils {
* @throws URISyntaxException
*/
public void openAuthorizationPage() throws IOException, URISyntaxException {
Desktop desktop = Desktop.getDesktop();
Desktop desktop = Desktop.getDesktop();
// properties moved to early init dwm08
//if (clientId == null) fetchOauthProperties();
......@@ -208,13 +217,13 @@ public class OAuthUtils {
// throw new IOException("Either scope or resource must be provided to authenticate.");
// }
// check if the "browse" Desktop action is suppported (many Linux DEs cannot directly
// launch browsers!)
if(desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new URI(url));
} else { // otherwise, display a dialog box for the user to copy the URL manually.
MessageUtils.showMessage("Copy this authorization URL into your web browser: " + url);
}
// check if the "browse" Desktop action is suppported (many Linux DEs cannot directly
// launch browsers!)
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new URI(url));
} else { // otherwise, display a dialog box for the user to copy the URL manually.
MessageUtils.showMessage("Copy this authorization URL into your web browser: " + url);
}
// if the listener is not active, prompt the user
// for the access token
......@@ -330,29 +339,26 @@ public class OAuthUtils {
*
* @throws IOException
*/
private void fetchUserProfile() throws IOException {
// dwm08 - removing functionality to get user profile info from microsoft oauth. Just not worth the trouble
// JWT jwt = JWT.decode(accessToken);
// Map<String, Claim> claims = jwt.getClaims();
// for (String claim: claims.keySet()) {
// System.out.println(claim + " = " + claims.get(claim).asString());
// }
// currentUserName = claims.get("unique_name").asString();
public JsonObject fetchUserProfile() throws IOException {
try {
URL url = new URL("https://www.googleapis.com/plus/v1/people/me?access_token=" + accessToken);
URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken);
String response = HttpUtils.getInstance().getContentsAsJSON(url);
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(response).getAsJsonObject();
currentUserName = obj.get("displayName").getAsString();
} catch (Throwable exception){
}
currentUserName = obj.get("name").getAsString();
currentUserEmail = obj.get("email").getAsString();
currentUserID = obj.get("id").getAsString();
return obj;
} catch (Throwable exception) {
log.error(exception);
return null;
}
}
public String getAccessToken() {
// Check expiration time, with 1 minute cushion
......@@ -428,4 +434,89 @@ public class OAuthUtils {
}
}
/**
* Try to login to secure server. dwm08
*/
public static void doSecureLogin() {
// if user is not currently logged in, attempt to
// log in user if not logged in dwm08
if (!OAuthUtils.getInstance().isLoggedIn()) {
try {
OAuthUtils.getInstance().openAuthorizationPage();
} catch (Exception ex) {
MessageUtils.showErrorMessage("Error fetching oAuth tokens. See log for details", ex);
log.error("Error fetching oAuth tokens", ex);
}
}
// wait until authentication successful or 1 minute -
// dwm08
int i = 0;
while (!OAuthUtils.getInstance().isLoggedIn() && i < 600) {
++i;
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
/**
* Generate a set of all urls in the sessino file
*
* @param sessionPath
* @return list of urls
*/
public static Set<String> findUrlsInSessionFile(String sessionPath) {
BufferedReader br = null;
HashSet<String> urlSet = new HashSet<>();
try {
br = new BufferedReader(new FileReader(new File(sessionPath)));
String line;
while ((line = br.readLine()) != null) {
int start = line.indexOf("http");
if (start != -1) {
int mid = line.indexOf("://", start);
int end = line.indexOf("/", mid + 3);
String url = line.substring(start, end);
urlSet.add(url);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
}
}
}
return urlSet;
}
/**
* Check if any reference in the session file refers to a server protected
* by the oauth protocol. If so, check to see if the user is logged in. If
* user is not logged in, put up login prompt.
*
* @param sessionPath
*/
public static void checkServerLogin(String sessionPath) {
Set<String> urlSet = findUrlsInSessionFile(sessionPath);
if (urlSet.size() > 0) {
for (String url : urlSet) {
if (OAuthUtils.isGoogleCloud(url)) {
OAuthUtils.doSecureLogin();
// user is logged in. Can proceed with the load
return;
}
}
}
}
}
......@@ -7,7 +7,6 @@ import java.util.Arrays;
*/
final public class Constants {
private Constants() {} // Prevent instantiation
// Preference sets
......@@ -248,6 +247,10 @@ final public class Constants {
// Letter of support dialog
public static final String SHOW_LOS = "showLOS";
// Experimental
public static final String SCORE_VARIANTS = "SCORE_VARIANTS";
/**
* List of keys that affect the alignments loaded. This list is used to trigger a reload, if required.
* Not all alignment preferences need trigger a reload, this is a subset.
......