/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2016 Neil C Smith. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 3 for more details. * * You should have received a copy of the GNU General Public License version 3 * along with this work; if not, see http://www.gnu.org/licenses/ * * * Please visit http://neilcsmith.net if you need additional information or * have any questions. */ package net.neilcsmith.praxis.live.project; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; import net.neilcsmith.praxis.live.project.api.ExecutionLevel; import net.neilcsmith.praxis.live.project.api.PraxisProjectProperties; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileRenameEvent; import org.openide.filesystems.FileUtil; /** * * @author Neil C Smith (http://neilcsmith.net) */ public class ProjectPropertiesImpl extends PraxisProjectProperties { private final static FileObject[] FILEOBJECT_ARRAY = new FileObject[0]; private final Set<FileObject> buildFiles; private final Set<FileObject> runFiles; private final PropertyChangeSupport pcs; private final DefaultPraxisProject project; private final FileListener listener; ProjectPropertiesImpl(DefaultPraxisProject project) { this.project = project; buildFiles = new LinkedHashSet<>(); runFiles = new LinkedHashSet<>(); pcs = new PropertyChangeSupport(this); listener = new FileListener(); project.getProjectDirectory().addRecursiveListener(listener); } @Override public synchronized boolean addProjectFile(ExecutionLevel level, FileObject file) { Set<FileObject> set; if (level == ExecutionLevel.BUILD) { set = buildFiles; } else if (level == ExecutionLevel.RUN) { set = runFiles; } else { throw new IllegalArgumentException("Unknown build level"); } boolean changed = set.add(file); if (changed) { pcs.firePropertyChange(PROP_FILES_CHANGED, null, null); } return changed; } @Override public synchronized boolean removeProjectFile(ExecutionLevel level, FileObject file) { Set<FileObject> set; if (level == ExecutionLevel.BUILD) { set = buildFiles; } else if (level == ExecutionLevel.RUN) { set = runFiles; } else { throw new IllegalArgumentException("Unknown build level"); } boolean changed = set.remove(file); if (changed) { pcs.firePropertyChange(PROP_FILES_CHANGED, null, null); } return changed; } @Override public synchronized FileObject[] getProjectFiles(ExecutionLevel level) { if (level == ExecutionLevel.BUILD) { return buildFiles.toArray(FILEOBJECT_ARRAY); } else if (level == ExecutionLevel.RUN) { return runFiles.toArray(FILEOBJECT_ARRAY); } else { throw new IllegalArgumentException(); } } public synchronized void setProjectFiles(ExecutionLevel level, FileObject[] files) { for (FileObject file : files) { checkFile(file); } if (level == ExecutionLevel.BUILD) { buildFiles.clear(); buildFiles.addAll(Arrays.asList(files)); } else if (level == ExecutionLevel.RUN) { runFiles.clear(); runFiles.addAll(Arrays.asList(files)); } else { throw new IllegalArgumentException("Unknown build level"); } pcs.firePropertyChange(PROP_FILES_CHANGED, null, null); } private void checkFile(FileObject file) { if (!FileUtil.isParentOf(project.getProjectDirectory(), file)) { throw new IllegalArgumentException("All files must be contained in project"); } } @Override public void addPropertyChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } @Override public void removePropertyChangeListener(PropertyChangeListener listener) { pcs.removePropertyChangeListener(listener); } private class FileListener extends FileChangeAdapter { @Override public void fileDeleted(FileEvent fe) { synchronized (ProjectPropertiesImpl.this) { FileObject file = fe.getFile(); boolean changed = false; if (buildFiles.remove(file)) { changed = true; } if (runFiles.remove(file)) { changed = true; } if (changed) { pcs.firePropertyChange(PROP_FILES_CHANGED, null, null); } } } @Override public void fileRenamed(FileRenameEvent fe) { synchronized (ProjectPropertiesImpl.this) { pcs.firePropertyChange(PROP_FILES_CHANGED, null, null); } } } }