/* * The MIT License * * Copyright 2013 Andreas Giemza. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package de.andreasgiemza.jgeagle.repo; import de.andreasgiemza.jgeagle.repo.data.GetRepoFiles; import de.andreasgiemza.jgeagle.helper.DiffImage; import de.andreasgiemza.jgeagle.helper.Eagle; import de.andreasgiemza.jgeagle.options.Options; import de.andreasgiemza.jgeagle.repo.data.EagleFile; import de.andreasgiemza.jgeagle.repo.rcs.JGit; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.revwalk.RevCommit; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * * @author Andreas Giemza */ public class Repo { private final JGit jGit; private final String repoName; private final List<EagleFile> eagleFiles = new LinkedList<>(); public Repo(Options options, Path directory) throws IOException, GitAPIException { Path repoDirectory = directory.resolve(".git"); if (Files.exists(repoDirectory)) { jGit = new JGit(repoDirectory); repoName = directory.getName(directory.getNameCount() - 1).toString(); Files.walkFileTree(directory, new GetRepoFiles(directory, eagleFiles)); } else { throw new IOException(); } } public String getRepoName() { return repoName; } public List<EagleFile> getEagleFiles() { return eagleFiles; } public void getEagleFileLogAndStatus(Options options, EagleFile eagleFile) { if (eagleFile.isWorkingCopychanges() == null || options.getPropFollowGitAsBoolean() != eagleFile.isFollow()) { eagleFile.setFollow(options.getPropFollowGitAsBoolean()); eagleFile.clearData(); try { eagleFile.setWorkingCopychanges( jGit.checkForWorkingCopyChanges(eagleFile.getRepoFile())); if (eagleFile.isWorkingCopychanges()) { eagleFile.setWorkingCopyLastModified( new Date(Files.getLastModifiedTime( eagleFile.getFile()).toMillis())); } jGit.getFileHistory( options.getPropFollowGitAsBoolean(), eagleFile.getRepoFile(), eagleFile.getCommits(), eagleFile.getRenames()); } catch (IOException | GitAPIException ex) { Logger.getLogger(Repo.class.getName()).log(Level.SEVERE, null, ex); } } } private Path buildPath( Options options, RevCommit revCommit, EagleFile eagleFile, String fileExtension) { Path path; if (revCommit != null) { path = options.getReposDir() .resolve(repoName) .resolve("images") .resolve(revCommit.getName()); if (eagleFile.getRepoFile().getParent() != null) { path = path.resolve(eagleFile.getRepoFile().getParent()); } } else { path = options.getTempDir(); } return path.resolve(eagleFile.getFileName() + fileExtension); } public int getorCreateSheetCountFile(Options options, RevCommit revCommit, EagleFile eagleFile, String fileName) { Path countFile = buildPath(options, revCommit, eagleFile, "-SHEETCOUNT.txt"); if (!Files.exists(countFile)) { createSheetCountFile(options, eagleFile, revCommit, fileName); } try { return Integer.parseInt( Files.readAllLines( countFile, Charset.defaultCharset()).get(0)); } catch (IOException ex) { return 0; } } private void createSheetCountFile( Options options, EagleFile eagleFile, RevCommit revCommit, String fileName) { Path countFile = buildPath(options, revCommit, eagleFile, "-SHEETCOUNT.txt"); try { if (!Files.exists(countFile)) { Path schematicFile; if (revCommit != null) { schematicFile = options.getTempDir().resolve(fileName); } else { schematicFile = eagleFile.getFile(); } if (!Files.exists(schematicFile)) { jGit.extractFile( schematicFile, revCommit, eagleFile.getRepoFile(), eagleFile.getRenames()); } try { Files.copy( options.getPropEagleBinaryAsPath().getParent().resolve("..").normalize().resolve("doc").resolve("eagle.dtd"), options.getTempDir().resolve("eagle.dtd")); } catch (FileAlreadyExistsException ex) { } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(schematicFile.toFile()); document.getDocumentElement().normalize(); NodeList sheets = document.getElementsByTagName("sheet"); if (!Files.exists(countFile.getParent())) { Files.createDirectories(countFile.getParent()); } String count = "" + sheets.getLength(); try (FileOutputStream fos = new FileOutputStream(countFile.toFile())) { fos.write(count.getBytes()); fos.flush(); } } } catch (IOException | SAXException | ParserConfigurationException ex) { Logger.getLogger(Repo.class.getName()).log(Level.SEVERE, null, ex); } } public Path getOrCreateBoardDiffImage( Options options, EagleFile eagleFile, RevCommit oldCommit, RevCommit newCommit, String layer) { Path oldImageFile = getOrCreateBoardImage(options, oldCommit, eagleFile, "old.brd", layer); Path newImageFile = getOrCreateBoardImage(options, newCommit, eagleFile, "new.brd", layer); Path diffImageFile = buildDiffPath( options, eagleFile, oldCommit, newCommit, "-LAYER_" + layer + "-DPI_" + options.getPropBoardDpiAsInt() + "-ALPHA_" + options.getPropUnchangedBoardAlphaAsDouble() + ".png"); if (!Files.exists(diffImageFile) && Files.exists(oldImageFile) && Files.exists(newImageFile)) { try { DiffImage.create( oldImageFile, newImageFile, diffImageFile, options.getPropBoardBackground(), options.getPropUnchangedBoardAlphaAsDouble(), options.getPropAddedElementColor(), options.getPropRemovedElementColor(), options.getPropUndefinedColor()); } catch (IOException ex) { return null; } } return diffImageFile; } public Path getOrCreateBoardImage( Options options, RevCommit revCommit, EagleFile eagleFile, String tempFile, String layer) { try { Path imageFile = buildPath( options, revCommit, eagleFile, eagleFile.getFileName() + "-LAYER_" + layer + "-DPI_" + options.getPropBoardDpiAsInt() + ".png"); if (!Files.exists(imageFile)) { Path boardFile; if (revCommit != null) { boardFile = options.getTempDir().resolve(tempFile); } else { boardFile = eagleFile.getFile(); } if (!Files.exists(boardFile)) { jGit.extractFile( boardFile, revCommit, eagleFile.getRepoFile(), eagleFile.getRenames()); } String allLayers; switch (layer) { case "1": allLayers = layer + " " + options.getPropLayersTop(); break; case "16": allLayers = layer + " " + options.getPropLayersBottom(); break; default: allLayers = layer + " " + options.getPropLayersOther(); break; } Eagle.extractBoardImage( options.getPropEagleBinaryAsPath(), allLayers, imageFile, options.getPropBoardDpiAsInt(), boardFile); } return imageFile; } catch (IOException | InterruptedException ex) { return null; } } public Path getOrCreateSchematicDiffImage( Options options, EagleFile eagleFile, RevCommit oldCommit, RevCommit newCommit, int sheet) { Path oldImageFile = getOrCreateSchematicImage(options, oldCommit, eagleFile, "old.sch", sheet); Path newImageFile = getOrCreateSchematicImage(options, newCommit, eagleFile, "new.sch", sheet); Path diffImageFile = buildDiffPath( options, eagleFile, oldCommit, newCommit, "-SHEET_" + sheet + "-DPI_" + options.getPropSchematicDpiAsInt() + "-ALPHA_" + options.getPropUnchangedSchematicAlphaAsDouble() + ".png"); if (!Files.exists(diffImageFile) && Files.exists(oldImageFile) && Files.exists(newImageFile)) { try { DiffImage.create( oldImageFile, newImageFile, diffImageFile, options.getPropSchematicBackground(), options.getPropUnchangedSchematicAlphaAsDouble(), options.getPropAddedElementColor(), options.getPropRemovedElementColor(), options.getPropUndefinedColor()); } catch (IOException ex) { return null; } } return diffImageFile; } public Path getOrCreateSchematicImage( Options options, RevCommit revCommit, EagleFile eagleFile, String tempFile, int sheet) { try { Path imageFile = buildPath( options, revCommit, eagleFile, "-SHEET_" + sheet + "-DPI_" + options.getPropSchematicDpiAsInt() + ".png"); if (!Files.exists(imageFile)) { Path schematicFile; if (revCommit != null) { schematicFile = options.getTempDir().resolve(tempFile); } else { schematicFile = eagleFile.getFile(); } if (!Files.exists(schematicFile)) { jGit.extractFile( schematicFile, revCommit, eagleFile.getRepoFile(), eagleFile.getRenames()); } Eagle.extractSheetImage( options.getPropEagleBinaryAsPath(), sheet, imageFile, options.getPropSchematicDpiAsInt(), schematicFile); } return imageFile; } catch (IOException | InterruptedException ex) { return null; } } private Path buildDiffPath( Options options, EagleFile eagleFile, RevCommit oldCommit, RevCommit newCommit, String reaminingFilename) { Path path; if (newCommit != null) { path = options.getReposDir() .resolve(repoName) .resolve("diffImages") .resolve(oldCommit.getName() + "-" + newCommit.getName()); if (eagleFile.getRepoFile().getParent() != null) { path = path.resolve(eagleFile.getRepoFile().getParent()); } path = path.resolve(eagleFile.getFileName() + reaminingFilename); } else { path = options.getTempDir() .resolve("DIFF-" + eagleFile.getFileName() + reaminingFilename); } return path; } public List<String> getOrCreateLayersFile(Options options, RevCommit revCommit, EagleFile eagleFile, String fileName) { Path countFile = buildPath(options, revCommit, eagleFile, "-LAYERS.txt"); if (!Files.exists(countFile)) { createLayersFile(options, eagleFile, revCommit, fileName); } try { return Arrays.asList(Files.readAllLines( countFile, Charset.defaultCharset()).get(0).split(";")); } catch (IOException ex) { return new LinkedList<>(); } } private void createLayersFile( Options options, EagleFile eagleFile, RevCommit revCommit, String fileName) { Path layersFile = buildPath(options, revCommit, eagleFile, "-LAYERS.txt"); try { if (!Files.exists(layersFile)) { Path boardFile; if (revCommit != null) { boardFile = options.getTempDir().resolve(fileName); } else { boardFile = eagleFile.getFile(); } if (!Files.exists(boardFile)) { jGit.extractFile( boardFile, revCommit, eagleFile.getRepoFile(), eagleFile.getRenames()); } try { Files.copy( options.getPropEagleBinaryAsPath().getParent().resolve("..").normalize().resolve("doc").resolve("eagle.dtd"), options.getTempDir().resolve("eagle.dtd")); } catch (FileAlreadyExistsException ex) { } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(boardFile.toFile()); document.getDocumentElement().normalize(); NodeList layers = document.getElementsByTagName("layer"); String layerString = ""; boolean first = true; for (int i = 0; i < layers.getLength(); i++) { Element layer = (Element) layers.item(i); if (Integer.parseInt(layer.getAttribute("number")) <= 16 && "yes".equals(layer.getAttribute("active"))) { if (first) { first = false; } else { layerString += ";"; } layerString += layer.getAttribute("number"); } } if (!Files.exists(layersFile.getParent())) { Files.createDirectories(layersFile.getParent()); } try (FileOutputStream fos = new FileOutputStream(layersFile.toFile())) { fos.write(layerString.getBytes()); fos.flush(); } } } catch (IOException | SAXException | ParserConfigurationException ex) { Logger.getLogger(Repo.class.getName()).log(Level.SEVERE, null, ex); } } }