You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
402 lines
15 KiB
402 lines
15 KiB
/*
|
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
package com.jme3.gde.materialdefinition;
|
|
|
|
import java.beans.PropertyChangeEvent;
|
|
import java.beans.PropertyChangeListener;
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.BufferedInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Properties;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import org.netbeans.api.project.Project;
|
|
import org.openide.filesystems.FileLock;
|
|
import org.openide.filesystems.FileObject;
|
|
import org.openide.filesystems.FileUtil;
|
|
import org.openide.loaders.DataFolder;
|
|
import org.openide.util.Exceptions;
|
|
import org.openide.util.Mutex;
|
|
import org.openide.util.Mutex.Action;
|
|
|
|
/**
|
|
* Global object to access actual jME3 data within an AssetDataObject, available
|
|
* through the Lookup of any AssetDataObject. AssetDataObjects that wish to use
|
|
*
|
|
* @author normenhansen
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public class MatDefMetaData {
|
|
|
|
private static final Logger logger = Logger.getLogger(MatDefMetaData.class.getName());
|
|
private final List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
|
|
private final Mutex propsMutex = new Mutex();
|
|
private final Properties props = new Properties();
|
|
private static final Properties defaultProps = new Properties();
|
|
|
|
static {
|
|
defaultProps.put("Default/position", "0,120");
|
|
defaultProps.put("Default/MatParam.Color", "438,351");
|
|
defaultProps.put("Default/Default/ColorMult", "605,372");
|
|
defaultProps.put("Default/WorldParam.WorldViewProjectionMatrix", "33,241");
|
|
defaultProps.put("Default/color", "0,478");
|
|
defaultProps.put("Default/Default/CommonVert", "211,212");
|
|
}
|
|
private MatDefDataObject file;
|
|
private String extension = "jmpdata";
|
|
private Date lastLoaded;
|
|
private FileObject folder;
|
|
private FileObject root;
|
|
|
|
// private XMLFileSystem fs;
|
|
public MatDefMetaData(MatDefDataObject file) {
|
|
try {
|
|
this.file = file;
|
|
getFolder();
|
|
FileObject primaryFile = file.getPrimaryFile();
|
|
|
|
if (primaryFile != null) {
|
|
extension = primaryFile.getExt() + "data";
|
|
}
|
|
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
|
|
public MatDefMetaData(MatDefDataObject file, String extension) {
|
|
this.file = file;
|
|
this.extension = extension;
|
|
}
|
|
|
|
public synchronized String getProperty(final String key) {
|
|
readProperties();
|
|
return propsMutex.readAccess(new Action<String>() {
|
|
public String run() {
|
|
String prop = props.getProperty(key);
|
|
if (prop == null) {
|
|
return defaultProps.getProperty(key);
|
|
}
|
|
return prop;
|
|
}
|
|
});
|
|
}
|
|
|
|
public synchronized String getProperty(final String key, final String defaultValue) {
|
|
readProperties();
|
|
return propsMutex.readAccess(new Action<String>() {
|
|
public String run() {
|
|
String prop = props.getProperty(key);
|
|
if (prop == null) {
|
|
return defaultProps.getProperty(key);
|
|
}
|
|
return prop;
|
|
}
|
|
});
|
|
}
|
|
|
|
public synchronized String setProperty(final String key, final String value) {
|
|
readProperties();
|
|
String ret = propsMutex.writeAccess(new Action<String>() {
|
|
public String run() {
|
|
String ret = (String) props.setProperty(key, value);
|
|
return ret;
|
|
}
|
|
});
|
|
// writeProperties();
|
|
notifyListeners(key, ret, value);
|
|
return ret;
|
|
}
|
|
|
|
private void readProperties() {
|
|
propsMutex.writeAccess(new Runnable() {
|
|
public void run() {
|
|
try {
|
|
FileObject pFile = file.getPrimaryFile();
|
|
FileObject storageFolder = getFolder();
|
|
if (storageFolder == null) {
|
|
return;
|
|
}
|
|
final FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile)); //fs.findResource(fs.getRoot().getPath()+"/"+ file.getPrimaryFile().getName() + "." + extension);//
|
|
|
|
if (myFile == null) {
|
|
return;
|
|
}
|
|
final Date lastMod = myFile.lastModified();
|
|
if (!lastMod.equals(lastLoaded)) {
|
|
props.clear();
|
|
lastLoaded = lastMod;
|
|
InputStream in = null;
|
|
try {
|
|
in = new BufferedInputStream(myFile.getInputStream());
|
|
try {
|
|
props.load(in);
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
} catch (FileNotFoundException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
} finally {
|
|
try {
|
|
in.close();
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
logger.log(Level.FINE, "Read AssetData properties for {0}", file);
|
|
}
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void cleanup() {
|
|
propsMutex.writeAccess(new Runnable() {
|
|
public void run() {
|
|
OutputStream out = null;
|
|
FileLock lock = null;
|
|
try {
|
|
FileObject pFile = file.getPrimaryFile();
|
|
FileObject storageFolder = getFolder();
|
|
if (storageFolder == null) {
|
|
return;
|
|
}
|
|
|
|
FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));//FileUtil.findBrother(pFile, extension);//fs.findResource(fs.getRoot().getPath()+"/"+ pFile.getName() + "." + extension);//
|
|
if (myFile == null) {
|
|
return;
|
|
}
|
|
lock = myFile.lock();
|
|
myFile.delete(lock);
|
|
} catch (IOException e) {
|
|
Exceptions.printStackTrace(e);
|
|
} finally {
|
|
if (out != null) {
|
|
try {
|
|
out.close();
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
if (lock != null) {
|
|
lock.releaseLock();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
public void rename(final DataFolder df, final String name) {
|
|
propsMutex.writeAccess(new Runnable() {
|
|
public void run() {
|
|
OutputStream out = null;
|
|
FileLock lock = null;
|
|
try {
|
|
FileObject pFile = file.getPrimaryFile();
|
|
FileObject storageFolder = getFolder();
|
|
if (storageFolder == null) {
|
|
return;
|
|
}
|
|
|
|
FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));//FileUtil.findBrother(pFile, extension);//fs.findResource(fs.getRoot().getPath()+"/"+ pFile.getName() + "." + extension);//
|
|
if (myFile == null) {
|
|
return;
|
|
}
|
|
lock = myFile.lock();
|
|
if (df == null) {
|
|
myFile.rename(lock, getFileFullName(pFile).replaceAll(file.getName() + "." + extension, name + "." + extension), "");
|
|
} else {
|
|
myFile.rename(lock, FileUtil.getRelativePath(root, df.getPrimaryFile()).replaceAll("/", ".") + "." + pFile.getName(), extension);
|
|
}
|
|
} catch (IOException e) {
|
|
Exceptions.printStackTrace(e);
|
|
} finally {
|
|
if (out != null) {
|
|
try {
|
|
out.close();
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
if (lock != null) {
|
|
lock.releaseLock();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
public void duplicate(final DataFolder df, final String name) {
|
|
propsMutex.writeAccess(new Runnable() {
|
|
public void run() {
|
|
OutputStream out = null;
|
|
FileLock lock = null;
|
|
try {
|
|
FileObject pFile = file.getPrimaryFile();
|
|
FileObject storageFolder = getFolder();
|
|
if (storageFolder == null) {
|
|
return;
|
|
}
|
|
String newName = name;
|
|
if (newName == null) {
|
|
newName = file.getName();
|
|
}
|
|
String path = FileUtil.getRelativePath(root, df.getPrimaryFile()).replaceAll("/", ".") + "." + newName;
|
|
FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));
|
|
if (myFile == null) {
|
|
return;
|
|
}
|
|
|
|
myFile.copy(storageFolder, path, extension);
|
|
|
|
} catch (IOException e) {
|
|
Exceptions.printStackTrace(e);
|
|
} finally {
|
|
if (out != null) {
|
|
try {
|
|
out.close();
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
if (lock != null) {
|
|
lock.releaseLock();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
public void save() {
|
|
if (!props.isEmpty()) {
|
|
writeProperties();
|
|
}
|
|
}
|
|
|
|
private void writeProperties() {
|
|
//writeAccess because we write lastMod date, not because we write to the file
|
|
//the mutex protects the properties object, not the file
|
|
propsMutex.writeAccess(new Runnable() {
|
|
public void run() {
|
|
OutputStream out = null;
|
|
FileLock lock = null;
|
|
try {
|
|
FileObject pFile = file.getPrimaryFile();
|
|
FileObject storageFolder = getFolder();
|
|
if (storageFolder == null) {
|
|
return;
|
|
}
|
|
|
|
FileObject myFile = storageFolder.getFileObject(getFileFullName(pFile));//FileUtil.findBrother(pFile, extension);//fs.findResource(fs.getRoot().getPath()+"/"+ pFile.getName() + "." + extension);//
|
|
if (myFile == null) {
|
|
myFile = FileUtil.createData(storageFolder, getFileFullName(pFile));
|
|
}
|
|
lock = myFile.lock();
|
|
out = new BufferedOutputStream(myFile.getOutputStream(lock));
|
|
props.store(out, "");
|
|
out.flush();
|
|
lastLoaded = myFile.lastModified();
|
|
logger.log(Level.FINE, "Written AssetData properties for {0}", file);
|
|
} catch (IOException e) {
|
|
Exceptions.printStackTrace(e);
|
|
} finally {
|
|
if (out != null) {
|
|
try {
|
|
out.close();
|
|
} catch (IOException ex) {
|
|
Exceptions.printStackTrace(ex);
|
|
}
|
|
}
|
|
if (lock != null) {
|
|
lock.releaseLock();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private String getFileFullName(FileObject pFile) {
|
|
return FileUtil.getRelativePath(root, pFile).replaceAll("/", ".").replaceAll("j3md", extension);
|
|
}
|
|
|
|
protected void notifyListeners(String property, String before, String after) {
|
|
synchronized (listeners) {
|
|
for (Iterator<PropertyChangeListener> it = listeners.iterator(); it.hasNext();) {
|
|
PropertyChangeListener propertyChangeListener = it.next();
|
|
propertyChangeListener.propertyChange(new PropertyChangeEvent(this, property, before, after));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
|
synchronized (listeners) {
|
|
listeners.add(listener);
|
|
}
|
|
}
|
|
|
|
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
|
synchronized (listeners) {
|
|
listeners.remove(listener);
|
|
}
|
|
}
|
|
|
|
private FileObject getFolder() throws IOException {
|
|
if (folder == null) {
|
|
Project p = file.getLookup().lookup(Project.class);
|
|
if (p != null) {
|
|
root = p.getProjectDirectory();
|
|
|
|
FileObject jmedataFolder = root.getFileObject("/nbproject/jme3Data");
|
|
if (jmedataFolder == null) {
|
|
jmedataFolder = root.getFileObject("/nbproject");
|
|
if(jmedataFolder!=null){
|
|
jmedataFolder = jmedataFolder.createFolder("jme3Data");
|
|
}
|
|
}
|
|
return jmedataFolder;
|
|
}
|
|
}
|
|
return folder;
|
|
}
|
|
}
|
|
|