001/* 002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Jean-Marc Orliaguet, Chalmers 018 * 019 */ 020 021package org.nuxeo.theme.presets; 022 023import java.io.DataInputStream; 024import java.io.FileNotFoundException; 025import java.io.IOException; 026import java.io.InputStream; 027import java.io.StringReader; 028import java.io.StringWriter; 029import java.net.URL; 030import java.util.HashMap; 031import java.util.Map; 032 033import org.apache.commons.csv.CSVFormat; 034import org.apache.commons.csv.CSVParser; 035import org.apache.commons.csv.CSVPrinter; 036import org.apache.commons.csv.CSVRecord; 037import org.apache.commons.logging.Log; 038import org.apache.commons.logging.LogFactory; 039 040public class PaletteParser { 041 042 private static final Log log = LogFactory.getLog(PaletteParser.class); 043 044 public static Map<String, String> parse(URL url) { 045 Map<String, String> entries = new HashMap<>(); 046 InputStream in = null; 047 try { 048 in = url.openStream(); 049 entries = parse(in, url.getFile()); 050 } catch (FileNotFoundException e) { 051 log.error("File not found: " + url); 052 } catch (IOException e) { 053 log.error("Could not open file: " + url); 054 } catch (PaletteIdentifyException e) { 055 log.error("Could not identify palette type: " + url); 056 } catch (PaletteParseException e) { 057 log.error("Could not parse palette: " + url); 058 } finally { 059 if (in != null) { 060 try { 061 in.close(); 062 } catch (IOException e) { 063 log.error(e, e); 064 } finally { 065 in = null; 066 } 067 } 068 } 069 return entries; 070 } 071 072 public static boolean checkSanity(byte[] bytes) { 073 return false; 074 } 075 076 public static String rgbToHex(int r, int g, int b) { 077 final StringBuffer hexcolor = new StringBuffer("#"); 078 final int[] rgb = { r, g, b }; 079 for (final int val : rgb) { 080 if (val < 16) { 081 hexcolor.append("0"); 082 } 083 hexcolor.append(Integer.toHexString(val)); 084 } 085 // optimize #aabbcc to #abc 086 if (hexcolor.charAt(1) == hexcolor.charAt(2) && hexcolor.charAt(3) == hexcolor.charAt(4) 087 && hexcolor.charAt(5) == hexcolor.charAt(6)) { 088 return String.format("#%s%s%s", hexcolor.charAt(1), hexcolor.charAt(4), hexcolor.charAt(6)); 089 } 090 return hexcolor.toString(); 091 } 092 093 public static PaletteFamily identifyPaletteType(byte[] bytes, String filename) throws PaletteIdentifyException { 094 if (filename.endsWith(".aco") && PhotoshopPaletteParser.checkSanity(bytes)) { 095 return PaletteFamily.PHOTOSHOP; 096 } else if (filename.endsWith(".gpl") && GimpPaletteParser.checkSanity(bytes)) { 097 return PaletteFamily.GIMP; 098 } else if (filename.endsWith(".properties") && PropertiesPaletteParser.checkSanity(bytes)) { 099 return PaletteFamily.PROPERTIES; 100 } 101 throw new PaletteIdentifyException(); 102 } 103 104 public static Map<String, String> parse(InputStream in, String filename) throws IOException, 105 PaletteIdentifyException, PaletteParseException { 106 DataInputStream dis = new DataInputStream(in); 107 byte[] bytes = new byte[dis.available()]; 108 dis.read(bytes); 109 return parse(bytes, filename); 110 } 111 112 public static Map<String, String> parse(byte[] bytes, String filename) throws PaletteIdentifyException, 113 PaletteParseException { 114 PaletteFamily paletteFamily = identifyPaletteType(bytes, filename); 115 if (paletteFamily == PaletteFamily.PHOTOSHOP) { 116 return PhotoshopPaletteParser.parse(bytes); 117 } else if (paletteFamily == PaletteFamily.GIMP) { 118 return GimpPaletteParser.parse(bytes); 119 } else if (paletteFamily == PaletteFamily.PROPERTIES) { 120 return PropertiesPaletteParser.parse(bytes); 121 } 122 if (paletteFamily == null) { 123 throw new PaletteParseException(); 124 } 125 return null; 126 } 127 128 public static String renderPaletteAsCsv(byte[] bytes, String fileName) { 129 StringWriter sw = new StringWriter(); 130 try (CSVPrinter writer = new CSVPrinter(sw, CSVFormat.DEFAULT.withDelimiter('\t'))) { 131 for (Map.Entry<String, String> entry : parse(bytes, fileName).entrySet()) { 132 writer.printRecord(entry.getKey(), entry.getValue()); 133 } 134 } catch (PaletteIdentifyException e) { 135 log.warn("Could not identify palette type: " + fileName); 136 } catch (PaletteParseException e) { 137 log.warn("Could not parse palette: " + fileName); 138 } catch (IOException e) { 139 log.error(e.getMessage(), e); 140 } 141 return sw.toString(); 142 } 143 144 public static Map<String, String> parseCsv(String text) { 145 Map<String, String> properties = new HashMap<>(); 146 if (text == null) { 147 return properties; 148 } 149 try (StringReader sr = new StringReader(text); 150 CSVParser reader = new CSVParser(sr, CSVFormat.DEFAULT.withDelimiter('\t'))) { 151 for (CSVRecord record : reader) { 152 properties.put(record.get(0), record.get(1)); 153 } 154 } catch (IOException e) { 155 log.error(e, e); 156 } 157 return properties; 158 } 159 160}