From e11ccc14af267112f9dfca79040d661fca47b808 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Mon, 13 May 2024 14:31:58 +0100 Subject: [PATCH] JAL-1054 Add wrappers for URL.openConnection(), URL.openStream() to allow following redirect from http to https --- src/jalview/bin/Cache.java | 16 +- src/jalview/ext/paradise/Annotate3D.java | 3 +- src/jalview/gui/UserQuestionnaireCheck.java | 11 +- src/jalview/io/BioJsHTMLOutput.java | 3 +- src/jalview/io/FileParse.java | 13 +- src/jalview/io/HTMLOutput.java | 3 +- src/jalview/io/IdentifyFile.java | 3 + src/jalview/project/Jalview2XML.java | 4 +- src/jalview/util/ChannelProperties.java | 2 +- src/jalview/util/HttpUtils.java | 103 ++++++++++- src/jalview/util/LaunchUtils.java | 2 +- src/jalview/ws/jws1/Annotate3D.java | 17 +- src/jalview/ws/jws2/JabaWsServerQuery.java | 10 +- src/jalview/ws/utils/UrlDownloadClient.java | 7 +- utils/install4j/auto_file_associations-i4j8.pl | 221 ------------------------ 15 files changed, 151 insertions(+), 267 deletions(-) delete mode 100755 utils/install4j/auto_file_associations-i4j8.pl diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index a64e869..136e2f7 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -67,6 +67,7 @@ import jalview.structure.StructureImportSettings; import jalview.urls.IdOrgSettings; import jalview.util.ChannelProperties; import jalview.util.ColorUtils; +import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.ws.sifts.SiftsSettings; @@ -410,7 +411,7 @@ public class Cache try { // props file provided as URL - fis = new URL(propertiesFile).openStream(); + fis = HttpUtils.openStream(new URL(propertiesFile)); if (!Jalview.quiet()) { jalview.bin.Console.outPrintln( @@ -497,7 +498,7 @@ public class Cache if (authorDetails != null) { URL localJarFileURL = new URL(authorDetails); - InputStream in = localJarFileURL.openStream(); + InputStream in = HttpUtils.openStream(localJarFileURL); applicationProperties.load(in); in.close(); } @@ -582,7 +583,7 @@ public class Cache URL url = new URL(remoteBuildPropertiesUrl); BufferedReader in = new BufferedReader( - new InputStreamReader(url.openStream())); + new InputStreamReader(HttpUtils.openStream(url))); Properties remoteBuildProperties = new Properties(); remoteBuildProperties.load(in); @@ -1451,10 +1452,11 @@ public class Cache if (customProxySet && // we have a username but no password for the scheme being // requested - (protocol.equalsIgnoreCase("http") - && (httpUser != null && httpUser.length() > 0 - && (httpPassword == null - || httpPassword.length == 0))) + (protocol.equalsIgnoreCase("http") + && (httpUser != null + && httpUser.length() > 0 + && (httpPassword == null + || httpPassword.length == 0))) || (protocol.equalsIgnoreCase("https") && (httpsUser != null && httpsUser.length() > 0 diff --git a/src/jalview/ext/paradise/Annotate3D.java b/src/jalview/ext/paradise/Annotate3D.java index 3817ee9..aafed20 100644 --- a/src/jalview/ext/paradise/Annotate3D.java +++ b/src/jalview/ext/paradise/Annotate3D.java @@ -36,6 +36,7 @@ import org.apache.http.message.BasicNameValuePair; import org.json.simple.parser.ContentHandler; import org.json.simple.parser.ParseException; +import jalview.util.HttpUtils; import jalview.util.JSONUtils; import jalview.util.MessageManager; import jalview.ws.HttpClientUtils; @@ -180,7 +181,7 @@ public class Annotate3D // return processJsonResponseFor(new // InputStreamReader(geturl.openStream())); ArrayList readers = new ArrayList<>(); - readers.add(new InputStreamReader(geturl.openStream())); + readers.add(new InputStreamReader(HttpUtils.openStream(geturl))); return readers.iterator(); } diff --git a/src/jalview/gui/UserQuestionnaireCheck.java b/src/jalview/gui/UserQuestionnaireCheck.java index 385eb57..004cf4a 100644 --- a/src/jalview/gui/UserQuestionnaireCheck.java +++ b/src/jalview/gui/UserQuestionnaireCheck.java @@ -20,15 +20,14 @@ */ package jalview.gui; -import jalview.bin.Cache; -import jalview.bin.Console; -import jalview.util.MessageManager; - import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; -import javax.swing.JOptionPane; +import jalview.bin.Cache; +import jalview.bin.Console; +import jalview.util.HttpUtils; +import jalview.util.MessageManager; public class UserQuestionnaireCheck implements Runnable { @@ -63,7 +62,7 @@ public class UserQuestionnaireCheck implements Runnable // see if we have already responsed to this questionnaire or get a new // qid/rid pair BufferedReader br = new BufferedReader( - new InputStreamReader(qurl.openStream())); + new InputStreamReader(HttpUtils.openStream(qurl))); String qresp; while ((qresp = br.readLine()) != null) { diff --git a/src/jalview/io/BioJsHTMLOutput.java b/src/jalview/io/BioJsHTMLOutput.java index 13bfb8c..9d9eaf8 100644 --- a/src/jalview/io/BioJsHTMLOutput.java +++ b/src/jalview/io/BioJsHTMLOutput.java @@ -37,6 +37,7 @@ import jalview.gui.AlignmentPanel; import jalview.gui.OOMWarning; import jalview.json.binding.biojs.BioJSReleasePojo; import jalview.json.binding.biojs.BioJSRepositoryPojo; +import jalview.util.HttpUtils; import jalview.util.MessageManager; public class BioJsHTMLOutput extends HTMLOutput @@ -178,7 +179,7 @@ public class BioJsHTMLOutput extends HTMLOutput try { URL resourceUrl = new URL(url); - is = new BufferedInputStream(resourceUrl.openStream()); + is = new BufferedInputStream(HttpUtils.openStream(resourceUrl)); BufferedReader br = new BufferedReader(new InputStreamReader(is)); responseStrBuilder = new StringBuilder(); String lineContent; diff --git a/src/jalview/io/FileParse.java b/src/jalview/io/FileParse.java index 1f51d8c..76aa2fa 100755 --- a/src/jalview/io/FileParse.java +++ b/src/jalview/io/FileParse.java @@ -25,6 +25,7 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; @@ -42,6 +43,7 @@ import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeatureSettingsModelI; import jalview.bin.Console; +import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; @@ -316,13 +318,15 @@ public class FileParse URLConnection _conn = url.openConnection(); if (_conn instanceof HttpURLConnection) { - HttpURLConnection conn = (HttpURLConnection) _conn; + HttpURLConnection conn = HttpUtils + .followConnection((HttpURLConnection) _conn); int rc = conn.getResponseCode(); if (rc != HttpURLConnection.HTTP_OK) { - throw new IOException( - "Response status from " + urlStr + " was " + rc); + throw new FileNotFoundException("Response status from " + urlStr + + " was " + conn.getResponseCode()); } + _conn = conn; } else { @@ -805,7 +809,8 @@ public class FileParse return new BufferedReader(new FileReader((File) file)); case URL: URL url = new URL(file.toString()); - in = new BufferedReader(new InputStreamReader(url.openStream())); + in = new BufferedReader( + new InputStreamReader(HttpUtils.openStream(url))); break; case RELATIVE_URL: // JalviewJS only bytes = Platform.getFileAsBytes(file.toString()); diff --git a/src/jalview/io/HTMLOutput.java b/src/jalview/io/HTMLOutput.java index 0b541e2..a17911c 100644 --- a/src/jalview/io/HTMLOutput.java +++ b/src/jalview/io/HTMLOutput.java @@ -35,6 +35,7 @@ import jalview.datamodel.AlignmentExportData; import jalview.gui.AlignmentPanel; import jalview.gui.IProgressIndicator; import jalview.io.exceptions.ImageOutputException; +import jalview.util.HttpUtils; import jalview.util.MessageManager; public abstract class HTMLOutput implements Runnable @@ -118,7 +119,7 @@ public abstract class HTMLOutput implements Runnable { try { - isReader = new InputStreamReader(url.openStream()); + isReader = new InputStreamReader(HttpUtils.openStream(url)); buffReader = new BufferedReader(isReader); String line; String lineSeparator = System.getProperty("line.separator"); diff --git a/src/jalview/io/IdentifyFile.java b/src/jalview/io/IdentifyFile.java index baee531..00e2872 100755 --- a/src/jalview/io/IdentifyFile.java +++ b/src/jalview/io/IdentifyFile.java @@ -94,6 +94,9 @@ public class IdentifyFile { return identify(parser); } + } catch (IOException e) + { + Console.error("Error whilst trying to read " + file, e); } catch (Exception e) { Console.error("Error whilst identifying " + file, e); diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index 983b512..de58f60 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -91,7 +91,6 @@ import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; -import jalview.datamodel.ContactListI; import jalview.datamodel.ContactMatrix; import jalview.datamodel.ContactMatrixI; import jalview.datamodel.DBRefEntry; @@ -99,7 +98,6 @@ import jalview.datamodel.FloatContactMatrix; import jalview.datamodel.GeneLocus; import jalview.datamodel.GraphLine; import jalview.datamodel.GroupSet; -import jalview.datamodel.GroupSetI; import jalview.datamodel.PDBEntry; import jalview.datamodel.Point; import jalview.datamodel.RnaViewerModel; @@ -3130,7 +3128,7 @@ public class Jalview2XML // jalview.bin.Console.outPrintln("Jalview2XML: opening url // jarInputStream for " // + _url); - return new JarInputStream(_url.openStream()); + return new JarInputStream(HttpUtils.openStream(_url)); } else { diff --git a/src/jalview/util/ChannelProperties.java b/src/jalview/util/ChannelProperties.java index c4c083f..a1cb1ba 100644 --- a/src/jalview/util/ChannelProperties.java +++ b/src/jalview/util/ChannelProperties.java @@ -97,7 +97,7 @@ public class ChannelProperties { try { - InputStream channelPropsIS = channelPropsURL.openStream(); + InputStream channelPropsIS = HttpUtils.openStream(channelPropsURL); tryChannelProps.load(channelPropsIS); channelPropsIS.close(); } catch (IOException e) diff --git a/src/jalview/util/HttpUtils.java b/src/jalview/util/HttpUtils.java index 5438d4e0..6ecfab2 100644 --- a/src/jalview/util/HttpUtils.java +++ b/src/jalview/util/HttpUtils.java @@ -45,7 +45,7 @@ public class HttpUtils InputStream is = null; try { - is = new URL(url).openStream(); + is = HttpUtils.openStream(new URL(url)); if (is != null) { return true; @@ -91,15 +91,108 @@ public class HttpUtils // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod(HttpMethod.HEAD); - connection.setDoInput(true); - connection.setUseCaches(false); connection.setConnectTimeout(300); connection.setReadTimeout(readTimeout); - return connection.getResponseCode() == 200; + + // HttpURLConnection doesn't follow redirects from http to https. It should! + HttpURLConnection conn = followConnection(connection); + return conn.getResponseCode() == 200; + } + + /** + * wrapper to follow a URL connection ALLOWING redirects from http to https + * + * @param URL + * url + * @return HttpUrlConnection conn + */ + public static HttpURLConnection openConnection(URL url) throws IOException + { + if (url == null) + { + return null; + } + HttpURLConnection conn = null; + if (url != null && url.getProtocol().startsWith("http")) + { + HttpURLConnection conn0 = (HttpURLConnection) url.openConnection(); + if (conn0 != null) + { + conn = HttpUtils.followConnection(conn0); + } + else + { + conn = conn0; + } + } + return conn; + } + + /** + * wrapper to follow a URL connection ALLOWING redirects from http to https + * + * @param HttpURLConnection + * conn0 + * @return HttpUrlConnection conn + */ + public static HttpURLConnection followConnection(HttpURLConnection conn0) + throws IOException + { + HttpURLConnection newConn = null; + URL url = conn0.getURL(); + if (url == null) + { + return null; + } + int response = conn0.getResponseCode(); + boolean followed = false; + if (response >= 300 && response < 400 && conn0.getFollowRedirects()) + { + // we are only checking for a redirect from http to https + if ("http".equals(url.getProtocol())) + { + URL loc = new URL(conn0.getHeaderField("Location")); + if (loc != null && "https".equals(loc.getProtocol())) + { + newConn = (HttpURLConnection) loc.openConnection(); + newConn.setRequestMethod(conn0.getRequestMethod()); + newConn.setDoInput(conn0.getDoInput()); + newConn.setUseCaches(conn0.getUseCaches()); + newConn.setConnectTimeout(conn0.getConnectTimeout()); + newConn.setReadTimeout(conn0.getReadTimeout()); + newConn.setInstanceFollowRedirects( + conn0.getInstanceFollowRedirects()); + followed = true; + } + } + } + return followed ? newConn : conn0; + } + + /** + * wrapper to follow a URL connection ALLOWING redirects from http to https + * and return the followed InputStream + * + * @param URL + * url + * @return HttpUrlConnection conn + */ + public static InputStream openStream(URL url) throws IOException + { + InputStream is = null; + if (url != null && url.getProtocol().startsWith("http")) + { + HttpURLConnection conn = HttpUtils + .followConnection((HttpURLConnection) url.openConnection()); + if (conn != null) + { + is = conn.getInputStream(); + } + } + return is; } public static String getUserAgent() diff --git a/src/jalview/util/LaunchUtils.java b/src/jalview/util/LaunchUtils.java index 4b443d3..404206b 100644 --- a/src/jalview/util/LaunchUtils.java +++ b/src/jalview/util/LaunchUtils.java @@ -107,7 +107,7 @@ public class LaunchUtils try { URL localFileURL = new URL(buildDetails); - InputStream in = localFileURL.openStream(); + InputStream in = HttpUtils.openStream(localFileURL); Properties buildProperties = new Properties(); buildProperties.load(in); in.close(); diff --git a/src/jalview/ws/jws1/Annotate3D.java b/src/jalview/ws/jws1/Annotate3D.java index 4165eae..f4acafa 100644 --- a/src/jalview/ws/jws1/Annotate3D.java +++ b/src/jalview/ws/jws1/Annotate3D.java @@ -20,13 +20,6 @@ */ package jalview.ws.jws1; -import jalview.datamodel.AlignmentI; -import jalview.io.FileFormat; -import jalview.io.FileParse; -import jalview.io.FormatAdapter; -import jalview.io.InputStreamParser; -import jalview.util.MessageManager; - import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; @@ -37,6 +30,14 @@ import java.net.URL; import java.net.URLEncoder; import java.util.Iterator; +import jalview.datamodel.AlignmentI; +import jalview.io.FileFormat; +import jalview.io.FileParse; +import jalview.io.FormatAdapter; +import jalview.io.InputStreamParser; +import jalview.util.HttpUtils; +import jalview.util.MessageManager; + public class Annotate3D { // protected BufferedReader in; @@ -181,7 +182,7 @@ public class Annotate3D "http://paradise-ibmc.u-strasbg.fr/webservices/annotate3d?data=" + content); BufferedReader is = new BufferedReader( - new InputStreamReader(url.openStream())); + new InputStreamReader(HttpUtils.openStream(url))); String str4; while ((str4 = is.readLine()) != null) { diff --git a/src/jalview/ws/jws2/JabaWsServerQuery.java b/src/jalview/ws/jws2/JabaWsServerQuery.java index 84aa1a6..559afac 100644 --- a/src/jalview/ws/jws2/JabaWsServerQuery.java +++ b/src/jalview/ws/jws2/JabaWsServerQuery.java @@ -23,10 +23,6 @@ */ package jalview.ws.jws2; -import jalview.bin.Console; -import jalview.ws.jws2.jabaws2.Jws2Instance; -import jalview.ws.jws2.jabaws2.Jws2InstanceFactory; - import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; @@ -37,6 +33,10 @@ import compbio.data.msa.Category; import compbio.data.msa.JABAService; import compbio.ws.client.Jws2Client; import compbio.ws.client.Services; +import jalview.bin.Console; +import jalview.util.HttpUtils; +import jalview.ws.jws2.jabaws2.Jws2Instance; +import jalview.ws.jws2.jabaws2.Jws2InstanceFactory; /** * @author JimP @@ -244,7 +244,7 @@ public class JabaWsServerQuery implements Runnable try { URL url = new URL(server); - url.openStream().close(); + HttpUtils.openStream(url).close(); result = true; } catch (MalformedURLException e) { diff --git a/src/jalview/ws/utils/UrlDownloadClient.java b/src/jalview/ws/utils/UrlDownloadClient.java index 91d88c2..362350d 100644 --- a/src/jalview/ws/utils/UrlDownloadClient.java +++ b/src/jalview/ws/utils/UrlDownloadClient.java @@ -21,8 +21,6 @@ package jalview.ws.utils; -import jalview.util.Platform; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -34,6 +32,9 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import jalview.util.HttpUtils; +import jalview.util.Platform; + public class UrlDownloadClient { /** @@ -57,7 +58,7 @@ public class UrlDownloadClient temp = Files.createTempFile(".jalview_", ".tmp"); URL url = new URL(urlstring); - rbc = Channels.newChannel(url.openStream()); + rbc = Channels.newChannel(HttpUtils.openStream(url)); fos = new FileOutputStream(temp.toString()); fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); diff --git a/utils/install4j/auto_file_associations-i4j8.pl b/utils/install4j/auto_file_associations-i4j8.pl deleted file mode 100755 index 31a4afa..0000000 --- a/utils/install4j/auto_file_associations-i4j8.pl +++ /dev/null @@ -1,221 +0,0 @@ -#!/usr/bin/env perl - -use strict; - -my $i4jversion = 8; -if ($ARGV[0] eq "-v") { - shift @ARGV; - $i4jversion = shift @ARGV; - die("-v i4jversion must be an integer [probably 7 or 8]") unless $i4jversion =~ m/^\d+$/; -} - -my $fileformats = $ARGV[0]; -$fileformats = "../../src/jalview/io/FileFormat.java" unless $fileformats; - -# default mimetype will be text/x-$shortname -# TODO: find an actual extension for mat, see JAL-Xxxxx for outstanding issues too -# TODO: look up standard mime type used for BLASTfmt matrices, etc -my $mimetypes = { - rnaml => "application/rnaml+xml", - biojson => "application/x-jalview-biojson+json", - jnet => "application/x-jalview-jnet+text", - features => "application/x-jalview-features+text", - scorematrix => "application/x-jalview-scorematrix+text", - pdb => "chemical/x-pdb", - mmcif => "chemical/x-cif", - mmcif2 => "chemical/x-mmcif", - jalview => "application/x-jalview+xml+zip", - jvl => "application/x-jalview-jvl+text", - annotations => "application/x-jalview-annotations+text", -}; - -my @dontaddshortname = qw(features json); -my @dontaddextension = qw(html xml json jar mfa fastq); -my $add_associations = { - biojson => {shortname=>"biojson",name=>"BioJSON",extensions=>["biojson"]}, - gff2 => {shortname=>"gff2",name=>"Generic Features Format v2",extensions=>["gff2"]}, - gff3 => {shortname=>"gff3",name=>"Generic Features Format v3",extensions=>["gff3"]}, - features => {shortname=>"features",name=>"Jalview Features",extensions=>["features","jvfeatures"]}, - annotations => {shortname=>"annotations",name=>"Jalview Annotations",extensions=>["annotations","jvannotations"]}, - mmcif => {shortname=>"mmcif",name=>"CIF",extensions=>["cif"]}, - mmcif2 => {shortname=>"mmcif2",name=>"mmCIF",extensions=>["mcif","mmcif"]}, - jvl => {shortname=>"jvl",name=>"Jalview Launch",extensions=>["jvl"],iconfile=>"jvl_file"}, - jnet => {shortname=>"jnet",name=>"JnetFile",extensions=>["concise","jnet"]}, - scorematrix => {shortname=>"scorematrix",name=>"Substitution Matrix",extensions=>["mat"]}, -}; -my $add_extensions = { - blc => ["blc"], -}; -my @put_first = qw(jalview jvl); - -my @non_primary = qw(mmcif mmcif2 pdb); - -my $v = ($i4jversion >= 8)?$i4jversion:""; -my $i4jtemplatefile = "file_associations_template-install4j${v}.xml"; -my $i4jtemplate; -my $mactemplatefile = "file_associations_template-Info_plist.xml"; -my $mactemplate; - -open(MT,"<$mactemplatefile") or die("Could not open '$mactemplatefile' for reading"); -while(){ - $mactemplate .= $_; -} -close(MT); -open(IT,"<$i4jtemplatefile") or die("Could not open '$i4jtemplatefile' for reading"); -while(){ - $i4jtemplate .= $_; -} -close(IT); -my $macauto; -my $i4jauto; - -my $macautofile = $mactemplatefile; -$macautofile =~ s/template/auto$1/; - -my $i4jautofile = $i4jtemplatefile; -$i4jautofile =~ s/template/auto$1/; - -for my $key (sort keys %$add_associations) { - my $a = $add_associations->{$key}; - warn("Known file association for $a->{shortname} (".join(",",@{$a->{extensions}}).")\n"); -} - -open(MA,">$macautofile") or die ("Could not open '$macautofile' for writing"); -print MA "CFBundleDocumentTypes\n\n\n"; - -open(IA,">$i4jautofile") or die ("Could not open '$i4jautofile' for writing"); - -open(IN, "<$fileformats") or die ("Could not open '$fileformats' for reading"); -my $id = 10000; -my $file_associations = {}; -while(my $line = ) { - $line =~ s/\s+/ /g; - $line =~ s/(^ | $)//g; - if ($line =~ m/^(\w+) ?\( ?"([^"]*)" ?, ?"([^"]*)" ?, ?(true|false) ?, ?(true|false) ?\)$/i) { - my $shortname = lc($1); - next if (grep($_ eq $shortname, @dontaddshortname)); - my $name = $2; - my $extensions = $3; - $extensions =~ s/\s+//g; - my @possextensions = map(lc($_),split(m/,/,$extensions)); - my @extensions; - my $addext = $add_extensions->{$shortname}; - if (ref($addext) eq "ARRAY") { - push(@possextensions, @$addext); - } - for my $possext (@possextensions) { - next if grep($_ eq $possext, @extensions); - next if grep($_ eq $possext, @dontaddextension); - push(@extensions,$possext); - } - next unless scalar(@extensions); - $file_associations->{$shortname} = { - shortname => $shortname, - name => $name, - extensions => \@extensions - }; - warn("Reading file association for $shortname (".join(",",@extensions).")\n"); - } -} -close(IN); - -my %all_associations = (%$file_associations, %$add_associations); - -my @ordered = (@put_first, @non_primary); -for my $key (sort keys %all_associations) { - next if grep($_ eq $key, @ordered); - push(@ordered, $key); -} -my $num = $#ordered + 1; - -warn("--\n"); - -my $i4jcount = 0; -for my $shortname (@ordered) { - my $a = $all_associations{$shortname}; - next if (ref($a) ne "HASH"); - - my $name = $a->{name}; - my $extensions = $a->{extensions}; - my $mimetype = $mimetypes->{$shortname}; - $mimetype = "application/x-$shortname+txt" unless $mimetype; - - my $iconfile = $a->{iconfile}; - $iconfile = "Jalview-File" unless $iconfile; - - my $primary = (! grep($_ eq $shortname, @non_primary)); - my $primarystring = $primary?"true":"false"; - my $role = $primary?"Editor":"Viewer"; - - my @extensions = @$extensions; - - my $xname = xml_escape($name); - my $xmimetype = xml_escape($mimetype); - my $xshortname = xml_escape($shortname); - my $xiconfile = xml_escape($iconfile); - my $xrole = xml_escape($role); - my $xROLE = xml_escape(uc($role)); - my $xprimarystring = xml_escape($primarystring); - - my $macentry = $mactemplate; - $macentry =~ s/\$\$NAME\$\$/$xname/g; - $macentry =~ s/\$\$SHORTNAME\$\$/$xshortname/g; - $macentry =~ s/\$\$MIMETYPE\$\$/$xmimetype/g; - $macentry =~ s/\$\$ICONFILE\$\$/$xiconfile/g; - $macentry =~ s/\$\$ROLE\$\$/$xrole/g; - $macentry =~ s/\$\$PRIMARY\$\$/$xprimarystring/g; - while ($macentry =~ m/\$\$([^\$]*)EXTENSIONS([^\$]*)\$\$/) { - my $pre = $1; - my $post = $2; - my $macextensions; - for my $ext (@extensions) { - my $xext = xml_escape($ext); - $macextensions .= $pre.$xext.$post; - } - $macentry =~ s/\$\$${pre}EXTENSIONS${post}\$\$/$macextensions/g; - } - print MA $macentry; - - my $i4jentry = $i4jtemplate; - $i4jentry =~ s/\$\$NAME\$\$/$xname/g; - $i4jentry =~ s/\$\$SHORTNAME\$\$/$xshortname/g; - $i4jentry =~ s/\$\$MIMETYPE\$\$/$xmimetype/g; - $i4jentry =~ s/\$\$ICONFILE\$\$/$xiconfile/g; - $i4jentry =~ s/\$\$PRIMARY\$\$/$xprimarystring/g; - $i4jentry =~ s/\$\$MACASSOCIATIONROLE\$\$/$xROLE/g; - - my $ext = join(",",sort(@extensions)); - my $xdisplayext = xml_escape(join(", ", map(".$_",sort(@extensions)))); - my $progresspercent = int(($i4jcount/$num)*100); - $progresspercent = 100 if $progresspercent > 100; - $i4jcount++; - my $xext = xml_escape($ext); - my $addunixextension = "true"; - - $i4jentry =~ s/\$\$ADDUNIXEXTENSION\$\$/$addunixextension/g; - $i4jentry =~ s/\$\$EXTENSION\$\$/$xext/g; - $i4jentry =~ s/\$\$DISPLAYEXTENSION\$\$/$xdisplayext/g; - $i4jentry =~ s/\$\$PROGRESSPERCENT\$\$/$progresspercent/g; - $i4jentry =~ s/\$\$ID\$\$/$id/g; - $id++; - $i4jentry =~ s/\$\$ID1\$\$/$id/g; - $id++; - $i4jentry =~ s/\$\$ID2\$\$/$id/g; - $id++; - - print IA $i4jentry; - - delete $all_associations{$shortname}; - warn("Writing entry for $name (".join(",",@$extensions).": $mimetype)\n"); -} - -close(IA); -print MA "\n"; -close(MA); - -sub xml_escape { - my $x = shift; - # stolen from Pod::Simple::XMLOutStream in base distro - $x =~ s/([^-\n\t !\#\$\%\(\)\*\+,\.\~\/\:\;=\?\@\[\\\]\^_\`\{\|\}a-zA-Z0-9])/'&#'.(ord($1)).';'/eg; - return $x; -} -- 1.7.10.2