/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ package datasource.explorer; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import ilog.cpl.datasource.IlpDefaultDataSource; import ilog.cpl.datasource.structure.IlpChild; import ilog.cpl.datasource.structure.IlpContainer; import ilog.cpl.model.IlpBeansObject; import ilog.cpl.model.IlpClass; import ilog.cpl.model.IlpDefaultClass; import ilog.cpl.model.IlpMutableClass; import ilog.cpl.model.IlpMutableClassManager; import ilog.cpl.model.IlpObject; /** * JTGO data source explorer sample. * See <A href="../../../index.html">index.html</A> for a description of this sample. */ public class FileDataSource extends IlpDefaultDataSource { /** * The IlpBeansClass instance that represents java.io.File */ IlpMutableClass fileClass; /** * The IlpClass instance that represents the roots */ IlpClass classOfRoots; /** * Constructor. */ public FileDataSource() { // call the constructor of IltDefaultDataSource super(); // Retrieve the File Java class as an IlpClass // By doing it this way, the java.io.File class is being considered as // a JavaBean, that is the class manager automatically create a // corresponding IlpBeansClass instance in which only the get methods // of java.io.File are translated as attributes. IlpMutableClassManager classManager = getContext().getClassManager(); fileClass = (IlpMutableClass)classManager.getClass(File.class.getName()); // Creates a sub class of the java.io.File IlpClass for root objects, // so it's possible to apply a different style on them. classOfRoots = new IlpDefaultClass("DirectoryRoot",fileClass,Collections.<IlpClass>emptyList()); fileClass.addSubClass(classOfRoots); classManager.addClass(classOfRoots); // loads the roots into the data source File[] rootdirs = File.listRoots(); addFiles(rootdirs, classOfRoots); } /** * Adds files to the data source. * @param files The java.io.Files that to be wrapped by IlpBeansObject. * @param ilpClass The IlpClass of the wrapping IlpBeansObject. */ protected synchronized void addFiles(File[] files, IlpClass ilpClass) { // Here we avoid calling IlpDefaultDataSource.addBean, as in this case // object would be inserted one by one. It would result in very low // performance, as each inserted object will result in one notification, // and each notification would result in a redrawing (in the tree for // example). So here the IlpBeansObject are created explicitely and // stored in a list before calling the addObjects method which will // result in only one notification List<IlpObject> filesAsIlpObjects = new ArrayList<IlpObject>(files.length); for (int i = 0; i < files.length; i++) { // use the file itself as the object identifier File id = files[i]; try { if (id.canRead()) { if (getObject(id) == null) { IlpBeansObject ilpObject = new IlpBeansObject(id,ilpClass,id); filesAsIlpObjects.add(ilpObject); } } } catch (Exception e) { // just ignore entry } } if (filesAsIlpObjects.size() != 0) addObjects(filesAsIlpObjects); } /** * This method in conjunction with the two previous classes * realizes load-on-demand in the data source. */ Override public synchronized IlpContainer getContainerInterface(Object idOrIlpObject) { // retrieve the object from the id or the object IlpObject object = idOrIlpObject instanceof IlpObject ? (IlpObject)idOrIlpObject : getObject(idOrIlpObject); // if we retrieved the object and it is an instance of fileClass if (object != null && fileClass.isAssignableFrom(object.getIlpClass())) { // retrieve the file, and test if it is a directory, if not, return null. File file = (File)((IlpBeansObject)object).getBean(); if (file.isDirectory()) return DIRECTORY_LOADER; else return null; } // for all other classes than fileObject, use the regular implementation, // So the FileDataSource can behave like an ordinary IltDefaultDataSource for // all other classes. return super.getContainerInterface(idOrIlpObject); } /** * Container interface for file objects. * This interface uses the listFiles method to get the list of * children. It tries to add them to the data source content, doing the * loading on demand, and then returns the list of identifiers. */ IlpContainer DIRECTORY_LOADER = new IlpContainer(){ Override public Collection<Object> getChildren(IlpObject object) { // the file is supposed to be a directory File directory = (File)((IlpBeansObject)object).getBean(); File[] files = directory.listFiles(); if (files == null) return Collections.emptyList(); List<Object> filesIds = new ArrayList<Object>(files.length); for (int i = 0; i < files.length; i++) { // 1st get all the identifiers filesIds.add(files[i]); } // then add the files addFiles(files, fileClass); return filesIds; } }; /** * This method in conjunction with the two previous classes * realizes load-on-demand in the data source. */ Override public synchronized IlpChild getChildInterface(Object idOrIlpObject) { // retrieve the object from the id or the object IlpObject object = idOrIlpObject instanceof IlpObject ? (IlpObject)idOrIlpObject : getObject(idOrIlpObject); // if the object is an instance of fileClass if (object != null && fileClass.isAssignableFrom(object.getIlpClass())) { // retrieve the file it contains and returns it (see FILE_PARENT below). File file = (File)((IlpBeansObject)object).getBean(); File parentFile = file.getParentFile(); if (parentFile != null) { return FILE_PARENT; } else { return null; } } return super.getChildInterface(idOrIlpObject); } /** * Child interface for file objects. * This interface uses the getParentFile method to get the parent. */ IlpChild FILE_PARENT = new IlpChild() { Override public Object getParent(IlpObject object) { File file = (File)((IlpBeansObject)object).getBean(); File parentFile = file.getParentFile(); return parentFile; } }; }