001/* 002 * (C) Copyright 2006-2010 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 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.theme.resources; 023 024import java.io.ByteArrayOutputStream; 025import java.io.File; 026import java.io.IOException; 027import java.io.InputStream; 028import java.net.URL; 029import java.util.ArrayList; 030import java.util.Arrays; 031import java.util.List; 032import java.util.Map; 033 034import org.apache.commons.logging.Log; 035import org.apache.commons.logging.LogFactory; 036import org.nuxeo.common.utils.FileUtils; 037import org.nuxeo.common.utils.ZipUtils; 038import org.nuxeo.theme.themes.ThemeManager; 039import org.yaml.snakeyaml.Yaml; 040 041public class BankManager { 042 private static final Log log = LogFactory.getLog(BankManager.class); 043 044 private static File BANKS_DIR; 045 046 private static List<String> FOLDER_NAMES = Arrays.asList("style", "preset", "image"); 047 048 private static final String CUSTOM_COLLECTION_DIRNAME = "custom"; 049 050 public static File getBanksDir() { 051 if (BANKS_DIR == null) { 052 BANKS_DIR = new File(ThemeManager.getThemeDir(), "banks"); 053 BANKS_DIR.mkdirs(); 054 } 055 return BANKS_DIR; 056 } 057 058 public static File getFile(String path) throws IOException { 059 if (!BankUtils.checkFilePath(path)) { 060 throw new IOException("File path not allowed: " + path); 061 } 062 return new File(getBanksDir(), path); 063 } 064 065 public static File getBankDir(String bankName) throws IOException { 066 return getFile(bankName); 067 } 068 069 public static List<String> getBankNames() { 070 List<String> names = new ArrayList<String>(); 071 File[] sortedFiles = BankUtils.listFilesSorted(getBanksDir()); 072 if (sortedFiles != null) { 073 for (File bankFile : sortedFiles) { 074 names.add(bankFile.getName()); 075 } 076 } 077 return names; 078 } 079 080 public static void setupBanks() { 081 for (String bankName : getBankNames()) { 082 try { 083 setupBankStructure(bankName); 084 } catch (IOException e) { 085 log.error("Could not create bank structure: " + bankName, e); 086 } 087 } 088 } 089 090 public static void setupBankStructure(String bankName) throws IOException { 091 for (String folderName : FOLDER_NAMES) { 092 String folderPath = String.format("/%s/%s", CUSTOM_COLLECTION_DIRNAME, folderName); 093 createFolder(bankName, folderPath); 094 } 095 } 096 097 /* 098 * Collections 099 */ 100 public static List<String> getCollections(String bank) throws IOException { 101 List<String> names = new ArrayList<String>(); 102 File file = getBankDir(bank); 103 if (file.exists()) { 104 for (File collectionFile : BankUtils.listFilesSorted(file)) { 105 names.add(collectionFile.getName()); 106 } 107 } 108 return names; 109 } 110 111 public static List<String> getItemsInCollection(String bank, String collection, String typeName) throws IOException { 112 List<String> names = new ArrayList<String>(); 113 String path = String.format("%s/%s/%s", bank, collection, typeName); 114 File file = getFile(path); 115 if (file.exists()) { 116 for (File item : BankUtils.listFilesSorted(file)) { 117 String itemName = item.getName(); 118 if (typeName.equals("style") && !itemName.endsWith(".css")) { 119 continue; 120 } 121 names.add(itemName); 122 } 123 } 124 return names; 125 } 126 127 public static File getStyleFile(String bank, String collection, String resource) throws IOException { 128 String path = String.format("%s/%s/style/%s", bank, collection, resource); 129 return getFile(path); 130 } 131 132 public static File getImageFile(String bank, String collection, String resource) throws IOException { 133 String path = String.format("%s/%s/image/%s", bank, collection, resource); 134 return getFile(path); 135 } 136 137 public static File getBankLogoFile(String bank) throws IOException { 138 String path = String.format("%s/logo.png", bank); 139 return getFile(path); 140 } 141 142 @SuppressWarnings("rawtypes") 143 public static File getStylePreviewFile(String bank, String collection, String resource) throws IOException { 144 Map<String, Object> info = getInfo(bank, collection, "style"); 145 146 if (!info.containsKey(resource)) { 147 throw new IOException("Style preview not found: " + resource); 148 } 149 150 Map value = (Map) info.get(resource); 151 if (!value.containsKey("preview")) { 152 throw new IOException("Style preview not found: " + resource); 153 } 154 155 String preview = (String) value.get("preview"); 156 String path = String.format("%s/%s/style/%s", bank, collection, preview); 157 158 File file = getFile(path); 159 if (!file.exists()) { 160 throw new IOException("Style preview not found: " + resource); 161 } 162 return file; 163 } 164 165 public static File getInfoFile(String bank, String collection, String typeName) throws IOException { 166 String path = String.format("%s/%s/%s/info.txt", bank, collection, typeName); 167 return getFile(path); 168 } 169 170 @SuppressWarnings("unchecked") 171 public static Map<String, Object> getInfo(String bank, String collection, String typeName) throws IOException { 172 File file = getInfoFile(bank, collection, typeName); 173 Yaml yaml = new Yaml(); 174 String content = ""; 175 if (file.exists()) { 176 content = BankUtils.getFileContent(file); 177 } 178 return (Map<String, Object>) yaml.load(content); 179 } 180 181 /* 182 * I/O 183 */ 184 public static void importBankData(String bankName, String collection, URL srcFileUrl) throws IOException { 185 if (CUSTOM_COLLECTION_DIRNAME.equals(collection)) { 186 throw new IOException("Bank collection name not allowed: " + CUSTOM_COLLECTION_DIRNAME); 187 } 188 InputStream in = null; 189 in = srcFileUrl.openStream(); 190 String path = String.format("%s/%s", bankName, collection); 191 File folder = getFile(path); 192 if (folder.exists()) { 193 FileUtils.deleteTree(folder); 194 } 195 folder.mkdir(); 196 ZipUtils.unzip(in, folder); 197 if (in != null) { 198 in.close(); 199 } 200 } 201 202 public static byte[] exportBankData(String bankName, String collection) throws IOException { 203 ByteArrayOutputStream out = new ByteArrayOutputStream(); 204 String path = String.format("%s/%s", bankName, collection); 205 File folder = getFile(path); 206 if (!folder.exists()) { 207 throw new IOException("Folder not found: " + path); 208 } 209 ZipUtils.zip(folder.listFiles(), out, null); 210 out.close(); 211 return out.toByteArray(); 212 } 213 214 public static File createFolder(String path, String folderName) throws IOException { 215 String folderPath = String.format("%s/%s", path, folderName); 216 File file = getFile(folderPath); 217 if (!file.exists()) { 218 file.mkdirs(); 219 } 220 return file; 221 } 222 223 public static File createFile(String path, String fileName, String content) throws IOException { 224 return createFile(path, fileName, content.getBytes()); 225 } 226 227 public static File createFile(String path, String fileName, byte[] data) throws IOException { 228 File file = new File(getFile(path), fileName); 229 file.createNewFile(); 230 FileUtils.writeFile(file, data); 231 return file; 232 } 233 234 public static void editFile(String path, String fileName, String content) throws IOException { 235 File file = new File(getFile(path), fileName); 236 FileUtils.writeFile(file, content); 237 } 238}