/** * Copyright 2014 * SMEdit https://github.com/StarMade/SMEdit * SMTools https://github.com/StarMade/SMTools * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. **/ package jo.sm.logic; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import jo.sm.data.ShapeLibraryEntry; import jo.sm.data.SparseMatrix; import jo.sm.logic.utils.FileUtils; import jo.sm.logic.utils.StringUtils; import jo.sm.logic.utils.XMLEditUtils; import jo.sm.logic.utils.XMLUtils; import jo.sm.mods.IBlocksPlugin; import jo.sm.ship.data.Block; import jo.util.Paths; import jo.vecmath.Point3i; import org.w3c.dom.Document; import org.w3c.dom.Node; public class ShapeLibraryLogic { private static long mLastRead = 0; private static final List<ShapeLibraryEntry> mEntries = new ArrayList<>(); private static final Logger log = Logger.getLogger(ShapeLibraryLogic.class.getName()); public static void update() { File plugins = new File(Paths.getPluginsDirectory()); File shapeLibDir = new File(plugins, "shapeLibrary"); if (!shapeLibDir.exists()) { mLastRead = 0; mEntries.clear(); return; } if (shapeLibDir.lastModified() <= mLastRead) { return; // up to date } // check files for (File shapeFile : shapeLibDir.listFiles()) { ShapeLibraryEntry entry = findByFile(shapeFile); if (entry != null) { if (entry.getLastRead() >= shapeFile.lastModified()) { continue; } else { mEntries.remove(entry); } } entry = new ShapeLibraryEntry(); entry.setShape(shapeFile); try { updateEntry(entry); } catch (IOException e) { log.log(Level.WARNING, "ShapeLibrary failed!", e); e.printStackTrace(); } mEntries.add(entry); } } private static void updateEntry(ShapeLibraryEntry entry) throws IOException { String xml = FileUtils.readFileAsString(entry.getShape().toString(), 1024); String name = getAttribute(xml, "name"); if (StringUtils.isTrivial(name)) { name = entry.getShape().getName(); if (name.endsWith(".xml")) { name = name.substring(0, name.length() - 4); } } entry.setName(name); String author = getAttribute(xml, "author"); if (StringUtils.isTrivial(author)) { author = "A. N. Onomous"; } entry.setAuthor(author); String lower = getAttribute(xml, "lower"); if (!StringUtils.isTrivial(lower)) { entry.setLower(new Point3i(lower)); } else { entry.setLower(new Point3i()); } String upper = getAttribute(xml, "upper"); if (!StringUtils.isTrivial(upper)) { entry.setUpper(new Point3i(upper)); } else { entry.setUpper(new Point3i()); } String classes = getAttribute(xml, "classifications"); if (!StringUtils.isTrivial(classes)) { classes = classes.toLowerCase(); if (classes.contains("ship")) { entry.getClassifications().add(IBlocksPlugin.TYPE_SHIP); } if (classes.contains("shop")) { entry.getClassifications().add(IBlocksPlugin.TYPE_SHOP); } if (classes.contains("station")) { entry.getClassifications().add(IBlocksPlugin.TYPE_STATION); } if (classes.contains("planet")) { entry.getClassifications().add(IBlocksPlugin.TYPE_PLANET); } if (classes.contains("floatingrock")) { entry.getClassifications().add(IBlocksPlugin.TYPE_FLOATINGROCK); } } if (entry.getClassifications().isEmpty()) { entry.getClassifications().add(IBlocksPlugin.TYPE_ALL); } entry.setLastRead(entry.getShape().lastModified()); } private static String getAttribute(String xml, String name) { int o = xml.indexOf(name); if (o < 0) { return null; } xml = xml.substring(o + name.length()).trim(); if (!xml.startsWith("=")) { return null; } xml = xml.substring(1).trim(); if (xml.startsWith("\"")) { xml = xml.substring(1); o = xml.indexOf("\""); if (o < 0) { return null; } return xml.substring(0, o); } if (xml.startsWith("\'")) { xml = xml.substring(1); o = xml.indexOf("\'"); if (o < 0) { return null; } return xml.substring(0, o); } return null; } public static ShapeLibraryEntry findByFile(File shapeFile) { for (ShapeLibraryEntry entry : mEntries) { if (shapeFile.equals(entry)) { return entry; } else { } } return null; } public static List<ShapeLibraryEntry> getEntries(int type) { update(); List<ShapeLibraryEntry> entries = new ArrayList<>(); for (ShapeLibraryEntry entry : mEntries) { if (isType(entry, type)) { entries.add(entry); } } return entries; } public static ShapeLibraryEntry getEntry(int unid) { for (ShapeLibraryEntry entry : mEntries) { if (entry.getUNID() == unid) { return entry; } } return null; } public static void addEntry(SparseMatrix<Block> grid, String name, String author, int type) { Document doc = GridLogic.toDocument(grid); Node root = doc.getFirstChild(); if (!StringUtils.isTrivial(name)) { XMLEditUtils.addAttribute(root, "name", name); } if (!StringUtils.isTrivial(author)) { XMLEditUtils.addAttribute(root, "author", author); } switch (type) { case IBlocksPlugin.TYPE_ALL: XMLEditUtils.addAttribute(root, "classifications", "all"); break; case IBlocksPlugin.TYPE_FLOATINGROCK: XMLEditUtils.addAttribute(root, "classifications", "floatingrock"); break; case IBlocksPlugin.TYPE_SHIP: XMLEditUtils.addAttribute(root, "classifications", "ship"); break; case IBlocksPlugin.TYPE_SHOP: XMLEditUtils.addAttribute(root, "classifications", "shop"); break; case IBlocksPlugin.TYPE_STATION: XMLEditUtils.addAttribute(root, "classifications", "station"); break; case IBlocksPlugin.TYPE_PLANET: XMLEditUtils.addAttribute(root, "classifications", "planet"); break; default: XMLEditUtils.addAttribute(root, "classifications", "all"); break; } File plugins = new File(Paths.getPluginsDirectory()); File shapeLibDir = new File(plugins, "shapeLibrary"); if (!shapeLibDir.exists()) { shapeLibDir.mkdirs(); } File shapeFile = new File(shapeLibDir, name + ".xml"); XMLUtils.writeFile(root, shapeFile); mLastRead = 0; } private static boolean isType(ShapeLibraryEntry entry, int type) { if (type == IBlocksPlugin.TYPE_ALL) { return true; } if (entry.getClassifications().isEmpty()) { return true; } if (entry.getClassifications().contains(IBlocksPlugin.TYPE_ALL)) { return true; } return entry.getClassifications().contains(type); } public static Map<String, Object> getEntryMap() { Map<String, Object> shapeMap = new HashMap<>(); int type = StarMadeLogic.getInstance().getCurrentModel().getType(); for (ShapeLibraryEntry entry : ShapeLibraryLogic.getEntries(type)) { shapeMap.put(entry.getName(), entry.getUNID()); } if (shapeMap.isEmpty()) { shapeMap.put("No shapes recorded", -1); } return shapeMap; } }