package jalview.io; import jalview.api.AlignViewportI; import jalview.api.FeatureRenderer; import jalview.api.FeaturesDisplayedI; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.json.binding.v1.AlignmentAnnotationPojo; import jalview.json.binding.v1.AlignmentPojo; import jalview.json.binding.v1.AnnotationPojo; import jalview.json.binding.v1.JalviewSettingsPojo; import jalview.json.binding.v1.JalviewSettingsPojo.JalviewBioJsColorSchemeMapper; import jalview.json.binding.v1.SequenceFeaturesPojo; import jalview.json.binding.v1.SequenceGrpPojo; import jalview.json.binding.v1.SequencePojo; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; public class JSONFile extends AlignFile { private ColourSchemeI colourScheme; // private static boolean seqFeaturesEnabled; private String jalviewVersion; private String webStartLaunchServletUrl; public static final String FILE_EXT = "json"; public static final String FILE_DESC = "JSON"; private String globalColorScheme; private boolean showSeqFeatures; private Hashtable seqMap; private FeaturesDisplayedI displayedFeatures; // private AlignViewportI viewport; private FeatureRenderer fr; private JSONExportSettings jsonExportSettings; public JSONFile() { super(); } public JSONFile(FileParse source) throws IOException { super(source); } public JSONFile(String inFile, String type) throws IOException { super(inFile, type); } @Override public void parse() throws IOException { StringBuilder jsonStringBuilder = new StringBuilder(); String currentLine; while ((currentLine = nextLine()) != null) { jsonStringBuilder.append(currentLine); } parse(jsonStringBuilder.toString()); } @Override public String print() { try { if (getJsonExportSettings() == null) { jsonExportSettings = new JSONExportSettings(); jsonExportSettings.setExportAnnotations(true); jsonExportSettings.setExportGroups(true); jsonExportSettings.setExportJalviewSettings(true); jsonExportSettings.setExportSequenceFeatures(true); } AlignmentPojo jsonAlignmentPojo = new AlignmentPojo(); if (getViewport() != null) { globalColorScheme = ColourSchemeProperty .getColourName(getViewport() .getGlobalColourScheme()); setDisplayedFeatures(getViewport().getFeaturesDisplayed()); showSeqFeatures = getViewport().isShowSequenceFeatures(); fr = getViewport().getFeatureRenderer(); // setSeqFeaturesEnabled(viewport.isShowSequenceFeatures()); } int count = 0; for (SequenceI seq : seqs) { StringBuilder name = new StringBuilder(); name.append(seq.getName()).append("/").append(seq.getStart()) .append("-").append(seq.getEnd()); SequencePojo jsonSeqPojo = new SequencePojo(); jsonSeqPojo.setId(seq.getName() + "_" + seq.hashCode()); jsonSeqPojo.setOrder(++count); jsonSeqPojo.setEnd(seq.getEnd()); jsonSeqPojo.setStart(seq.getStart()); jsonSeqPojo.setName(name.toString()); jsonSeqPojo.setSeq(seq.getSequenceAsString()); jsonAlignmentPojo.getSeqs().add(jsonSeqPojo); } if (jsonExportSettings.isExportJalviewSettings()) { jalviewVersion = jalview.bin.Cache.getProperty("VERSION"); webStartLaunchServletUrl = jalview.bin.Cache.getDefault( "www.jalview.org", "http://www.jalview.org") + "/services/launchApp"; JalviewSettingsPojo jvSettings = new JalviewSettingsPojo(); jvSettings.setGlobalColorScheme(globalColorScheme); jvSettings.setJalviewVersion(jalviewVersion); jvSettings.setWebStartUrl(webStartLaunchServletUrl); jvSettings.setShowSeqFeatures(showSeqFeatures); jsonAlignmentPojo.setJalviewSettings(jvSettings); } if (jsonExportSettings.isExportAnnotations()) { jsonAlignmentPojo .setAlignAnnotation(annotationToJsonPojo(annotations)); } if (jsonExportSettings.isExportSequenceFeatures()) { jsonAlignmentPojo .setSeqFeatures(sequenceFeatureToJsonPojo(seqs, fr)); } if (jsonExportSettings.isExportGroups() && seqGroups != null && seqGroups.size() > 0) { for (SequenceGroup seqGrp : seqGroups) { SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo(); seqGrpPojo.setGroupName(seqGrp.getName()); seqGrpPojo.setColourScheme(ColourSchemeProperty .getColourName(seqGrp.cs)); seqGrpPojo.setColourText(seqGrp.getColourText()); seqGrpPojo.setDescription(seqGrp.getDescription()); seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes()); seqGrpPojo.setDisplayText(seqGrp.getDisplayText()); seqGrpPojo.setEndRes(seqGrp.getEndRes()); seqGrpPojo.setStartRes(seqGrp.getStartRes()); seqGrpPojo.setShowNonconserved(seqGrp.getShowNonconserved()); for (SequenceI seq : seqGrp.getSequences()) { seqGrpPojo.getSeqsHash().add( seq.getName() + "_" + seq.hashCode()); } jsonAlignmentPojo.getSeqGroups().add(seqGrpPojo); } } com.json.JSONObject generatedJSon = new com.json.JSONObject( jsonAlignmentPojo); String jsonOutput = generatedJSon.toString(); return jsonOutput.replaceAll("xstart", "xStart").replaceAll("xend", "xEnd"); } catch (Exception e) { e.printStackTrace(); throw e; } } public static List sequenceFeatureToJsonPojo( List seqs, FeatureRenderer fr) { FeaturesDisplayedI displayedFeatures = (fr == null) ? null : fr .getFeaturesDisplayed(); List sequenceFeaturesPojo = new ArrayList(); for (SequenceI seq : seqs) { SequenceI dataSetSequence = seq.getDatasetSequence(); SequenceFeature[] seqFeatures = (dataSetSequence == null) ? null : seq.getDatasetSequence().getSequenceFeatures(); if (seqFeatures == null) { continue; } for (SequenceFeature sf : seqFeatures) { if (displayedFeatures != null && displayedFeatures.isVisible(sf.getType())) { SequenceFeaturesPojo jsonFeature = new SequenceFeaturesPojo( seq.getName() + "_" + seq.hashCode()); String featureColour = (fr == null) ? null : jalview.util.Format .getHexString(fr .findFeatureColour(Color.white, seq, seq.findIndex(sf.getBegin()))); jsonFeature.setXstart(seq.findIndex(sf.getBegin()) - 1); jsonFeature.setXend(seq.findIndex(sf.getEnd())); jsonFeature.setType(sf.getType()); jsonFeature.setDescription(sf.getDescription()); jsonFeature.setLinks(sf.links); jsonFeature.setOtherDetails(sf.otherDetails); jsonFeature.setScore(sf.getScore()); jsonFeature.setFillColor(featureColour); jsonFeature.setFeatureGroup(sf.getFeatureGroup()); sequenceFeaturesPojo.add(jsonFeature); } } } return sequenceFeaturesPojo; } public static List annotationToJsonPojo( Vector annotations) { List jsonAnnotations = new ArrayList(); if (annotations == null) { return jsonAnnotations; } for (AlignmentAnnotation annot : annotations) { AlignmentAnnotationPojo alignAnnotPojo = new AlignmentAnnotationPojo(); alignAnnotPojo.setDescription(annot.description); alignAnnotPojo.setLabel(annot.label); for (Annotation annotation : annot.annotations) { AnnotationPojo annotationPojo = new AnnotationPojo(); if (annotation != null) { annotationPojo.setDescription(annotation.description); annotationPojo.setValue(annotation.value); annotationPojo .setSecondaryStructure(annotation.secondaryStructure); annotationPojo.setDisplayCharacter(annotation.displayCharacter); alignAnnotPojo.getAnnotations().add(annotationPojo); } else { alignAnnotPojo.getAnnotations().add(annotationPojo); } } jsonAnnotations.add(alignAnnotPojo); } return jsonAnnotations; } @SuppressWarnings("unchecked") public JSONFile parse(String jsonAlignmentString) { try { JSONParser jsonParser = new JSONParser(); JSONObject alignmentJsonObj = (JSONObject) jsonParser .parse(jsonAlignmentString); JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs"); JSONArray alAnnotJsonArray = (JSONArray) alignmentJsonObj .get("alignAnnotation"); JSONArray jsonSeqArray = (JSONArray) alignmentJsonObj .get("seqFeatures"); JSONArray seqGrpJsonArray = (JSONArray) alignmentJsonObj .get("seqGroups"); JSONObject jvSettingsJsonObj = (JSONObject) alignmentJsonObj .get("jalviewSettings"); if (jvSettingsJsonObj != null) { String jsColourScheme = (String) jvSettingsJsonObj .get("globalColorScheme"); Boolean showFeatures = Boolean.valueOf(jvSettingsJsonObj.get( "showSeqFeatures").toString()); setColourScheme(getJalviewColorScheme(jsColourScheme)); // JSONFile.setSeqFeaturesEnabled(showFeatures); setShowSeqFeatures(showFeatures); } seqMap = new Hashtable(); for (Iterator sequenceIter = seqJsonArray.iterator(); sequenceIter .hasNext();) { JSONObject sequence = sequenceIter.next(); String sequcenceString = sequence.get("seq").toString(); String sequenceName = sequence.get("name").toString(); String seqUniqueId = sequence.get("id").toString(); int start = Integer.valueOf(sequence.get("start").toString()); int end = Integer.valueOf(sequence.get("end").toString()); Sequence seq = new Sequence(sequenceName, sequcenceString, start, end); seqs.add(seq); seqMap.put(seqUniqueId, seq); } parseFeatures(jsonSeqArray); for (Iterator seqGrpIter = seqGrpJsonArray.iterator(); seqGrpIter .hasNext();) { JSONObject seqGrpObj = seqGrpIter.next(); String grpName = seqGrpObj.get("groupName").toString(); String colourScheme = seqGrpObj.get("colourScheme").toString(); String description = (seqGrpObj.get("description") == null) ? null : seqGrpObj.get("description").toString(); boolean displayBoxes = Boolean.valueOf(seqGrpObj .get("displayBoxes").toString()); boolean displayText = Boolean.valueOf(seqGrpObj.get("displayText") .toString()); boolean colourText = Boolean.valueOf(seqGrpObj.get("colourText") .toString()); boolean showNonconserved = Boolean.valueOf(seqGrpObj.get( "showNonconserved").toString()); int startRes = Integer .valueOf(seqGrpObj.get("startRes").toString()); int endRes = Integer.valueOf(seqGrpObj.get("endRes").toString()); JSONArray seqsHashArray = (JSONArray) seqGrpObj.get("seqsHash"); ArrayList grpSeqs = new ArrayList(); if (seqsHashArray.size() > 0) { Iterator seqHashIter = seqsHashArray.iterator(); while (seqHashIter.hasNext()) { String seqHash = seqHashIter.next(); Sequence sequence = seqMap.get(seqHash); if (sequence != null) { grpSeqs.add(sequence); } } } ColourSchemeI scheme = getJalviewColorScheme(colourScheme); SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName, scheme, displayBoxes, displayText, colourText, startRes, endRes); seqGrp.setShowNonconserved(showNonconserved); seqGrp.setDescription(description); this.seqGroups.add(seqGrp); } for (Iterator alAnnotIter = alAnnotJsonArray.iterator(); alAnnotIter .hasNext();) { JSONObject alAnnot = alAnnotIter.next(); JSONArray annotJsonArray = (JSONArray) alAnnot.get("annotations"); Annotation[] annotations = new Annotation[annotJsonArray.size()]; int count = 0; for (Iterator annotIter = annotJsonArray.iterator(); annotIter .hasNext();) { JSONObject annot = annotIter.next(); if (annot == null) { annotations[count] = null; } else { float val = annot.get("value") == null ? null : Float .valueOf(annot.get("value").toString()); String desc = annot.get("description") == null ? null : annot .get("description").toString(); char ss = annot.get("secondaryStructure") == null ? null : annot.get("secondaryStructure").toString().charAt(0); String displayChar = annot.get("displayCharacter").toString(); annotations[count] = new Annotation(displayChar, desc, ss, val); } ++count; } AlignmentAnnotation alignAnnot = new AlignmentAnnotation(alAnnot .get("label").toString(), alAnnot.get("description") .toString(), annotations); this.annotations.add(alignAnnot); } } catch (Exception e) { e.printStackTrace(); } return this; } @SuppressWarnings("unchecked") private void parseFeatures(JSONArray jsonSeqFeatures) { if (jsonSeqFeatures != null) { for (Iterator seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr .hasNext();) { JSONObject jsonFeature = seqFeatureItr.next(); Long begin = (Long) jsonFeature.get("xStart"); Long end = (Long) jsonFeature.get("xEnd"); String type = (String) jsonFeature.get("type"); String featureGrp = (String) jsonFeature.get("featureGroup"); String descripiton = (String) jsonFeature.get("description"); String seqRef = (String) jsonFeature.get("sequenceRef"); Float score = Float.valueOf(jsonFeature.get("score").toString()); // Hashtable otherDetails = (Hashtable) jsonFeature // .get("otherDetails"); // sequenceFeature.otherDetails = otherDetails; Sequence seq = seqMap.get(seqRef); SequenceFeature sequenceFeature = new SequenceFeature(); JSONArray linksJsonArray = (JSONArray) jsonFeature.get("links"); if (linksJsonArray != null && linksJsonArray.size() > 0) { Iterator linkList = linksJsonArray.iterator(); while (linkList.hasNext()) { String link = linkList.next(); sequenceFeature.addLink(link); } } sequenceFeature.setFeatureGroup(featureGrp); sequenceFeature.setScore(score); sequenceFeature.setDescription(descripiton); sequenceFeature.setType(type); sequenceFeature.setBegin(seq.findPosition(begin.intValue())); sequenceFeature.setEnd(seq.findPosition(end.intValue()) - 1); seq.addSequenceFeature(sequenceFeature); } } } public static ColourSchemeI getJalviewColorScheme( String bioJsColourSchemeName) { ColourSchemeI jalviewColor = null; for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper .values()) { if (cs.getBioJsName().equalsIgnoreCase(bioJsColourSchemeName)) { jalviewColor = cs.getJvColourScheme(); break; } } return jalviewColor; } public void LoadAlignmentFeatures(AlignFrame af) { af.setShowSeqFeatures(isShowSeqFeatures()); af.changeColour(getColourScheme()); af.setMenusForViewport(); } public String getGlobalColorScheme() { return globalColorScheme; } public void setGlobalColorScheme(String globalColorScheme) { this.globalColorScheme = globalColorScheme; } public ColourSchemeI getColourScheme() { return colourScheme; } public void setColourScheme(ColourSchemeI colourScheme) { this.colourScheme = colourScheme; } public FeaturesDisplayedI getDisplayedFeatures() { return displayedFeatures; } public void setDisplayedFeatures(FeaturesDisplayedI displayedFeatures) { this.displayedFeatures = displayedFeatures; } public JSONExportSettings getJsonExportSettings() { return jsonExportSettings; } public void setJsonExportSettings(JSONExportSettings jsonExportSettings) { this.jsonExportSettings = jsonExportSettings; } public static String getJSONData(AlignViewportI av) { JSONFile jsonFile = new JSONFile(); jsonFile.setViewport(av); jsonFile.seqGroups = av.getAlignment().getGroups(); jsonFile.setDisplayedFeatures(av.getFeaturesDisplayed()); for (SequenceI seq : av.getAlignment().getSequences()) { jsonFile.seqs.add(seq); } // Add non auto calculated annotation to AlignFile for (AlignmentAnnotation annot : av.getAlignment() .getAlignmentAnnotation()) { if (annot != null && !annot.autoCalculated) { if (annot.label.equals("PDB.CATempFactor")) { continue; } jsonFile.annotations.add(annot); } } String jsonString = jsonFile.print(); return jsonString; } public boolean isShowSeqFeatures() { return showSeqFeatures; } public void setShowSeqFeatures(boolean showSeqFeatures) { this.showSeqFeatures = showSeqFeatures; } public class JSONExportSettings { private boolean exportSequence; private boolean exportSequenceFeatures; private boolean exportAnnotations; private boolean exportGroups; private boolean exportJalviewSettings; public boolean isExportSequence() { return exportSequence; } public void setExportSequence(boolean exportSequence) { this.exportSequence = exportSequence; } public boolean isExportSequenceFeatures() { return exportSequenceFeatures; } public void setExportSequenceFeatures(boolean exportSequenceFeatures) { this.exportSequenceFeatures = exportSequenceFeatures; } public boolean isExportAnnotations() { return exportAnnotations; } public void setExportAnnotations(boolean exportAnnotations) { this.exportAnnotations = exportAnnotations; } public boolean isExportGroups() { return exportGroups; } public void setExportGroups(boolean exportGroups) { this.exportGroups = exportGroups; } public boolean isExportJalviewSettings() { return exportJalviewSettings; } public void setExportJalviewSettings(boolean exportJalviewSettings) { this.exportJalviewSettings = exportJalviewSettings; } } }