Differences

This shows you the differences between two versions of the page.

Link to this comparison view

file_system [2012/03/31 22:04]
srdjan.lukovic [Live example]
file_system [2012/07/09 10:59] (current)
srdjan.lukovic [GUI Code]
Line 1: Line 1:
-====== File System Sample ====== +====== File System ====== 
-This is the most complex sample presented here. It is web based [[wp>Orthodox_file_manager#Orthodox_file_managers | Orthodox File Manager]] application.+ 
 +**File System** is a [[SOLoist Sample Applications|SOLoist sample application]] that represents a web-based [[wp>Orthodox_file_manager#Orthodox_file_managers | Orthodox File Manager]], with a personalized directory structure and standard file operations. It shows how a traditional concept of a file system can be implemented using the object paradigm with UML modeling and SOLoist UI. 
 + 
 +Each object of //Person// has an associated file system that starts with a root folder. When an object of //Person// is selected in the topmost suggestion box, the file system associated to that object is browsed in two parallel windows. 
 + 
 +A new file or folder can be created. Files or folders can be moved or copied, renamed, and deleted. Any of these commands (except renaming) can be performed on multiple items by selecting them from the list, or using the //Select all// checkbox. Selections are persisted, and every change in the folder structure is reflected immediately in the opposite window (if it is currently showing the same folder). Breadcrumbs are clickable, so one can return to any of the parent folders in one click.
  
 ==== Live example ==== ==== Live example ====
Line 6: Line 11:
 [[http://soloistdemo.org/SampleApplications/filesystem.html]]\\ [[http://soloistdemo.org/SampleApplications/filesystem.html]]\\
 [[http://soloistdemo.org/SampleApplications/oql?q=SELECT+d%2C+d.title%2C+d.description%2C+d.isPublic%2C+d.submitted%2C+d.date%2C+d.superItem%0AFROM+Document+d&hide=0 | OQL Query: Documents]] [[http://soloistdemo.org/SampleApplications/oql?q=SELECT+d%2C+d.title%2C+d.description%2C+d.isPublic%2C+d.submitted%2C+d.date%2C+d.superItem%0AFROM+Document+d&hide=0 | OQL Query: Documents]]
 +|{{screen:filesystem.png?350}}|
 ===== UML Model ===== ===== UML Model =====
 {{filesystem.png}} {{filesystem.png}}
  
 ===== Business Logic Code ===== ===== Business Logic Code =====
-...+<code java RenameDocument.java> 
 + @Override 
 + protected void execute() throws CommandPreconditionsException { 
 + Document d = document.val(); 
 +         
 +        d.rename(newTitle.val()); 
 +
 + @Override 
 + public boolean checkInputPinsCoverage() 
 +
 + if (document.val() == null) 
 +
 + throw new CommandPreconditionsException("Please, select document."); 
 +
 + if (newTitle.val() == null || (newTitle.val() != null && newTitle.val().isEmpty())) 
 +
 + throw new CommandPreconditionsException("Please, select new title."); 
 +
 + return true; 
 +
 +</code>
  
 +<code java CreateFolder.java>
 +    public void execute() 
 +    // -------------<SOL id="8e18bf85-cfe0-48d3-87af-91cbba029291:___throw__" />
 +    // -------------<LOS id="8e18bf85-cfe0-48d3-87af-91cbba029291:___throw__" />
 +    {
 +        // ---------<SOL id="8e18bf85-cfe0-48d3-87af-91cbba029291:___body___" />
 +    Folder f = in.val();
 +        
 +        f.createFolder(title.val());
 +        // ---------<LOS id="8e18bf85-cfe0-48d3-87af-91cbba029291:___body___" />
 +    }
 +
 +    // -------------<SOL id="31d4d83c-1416-4a69-9070-df78357687e5:___cend___" />
 + @Override
 + public boolean checkInputPinsCoverage()
 + {
 + if (in.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select input.");
 + }
 + return true;
 + }
 +    // -------------<LOS id="31d4d83c-1416-4a69-9070-df78357687e5:___cend___" />
 +</code>
 +
 +<code java CreateRegularDocument.java>
 +    public void execute() 
 +    // -------------<SOL id="116b4004-8141-4731-af83-2e12dbebbc8a:___throw__" />
 +    // -------------<LOS id="116b4004-8141-4731-af83-2e12dbebbc8a:___throw__" />
 +    {
 +        // ---------<SOL id="116b4004-8141-4731-af83-2e12dbebbc8a:___body___" />
 +    Folder f = in.val();
 +        
 +        f.createRegularDoc(title.val());
 +        // ---------<LOS id="116b4004-8141-4731-af83-2e12dbebbc8a:___body___" />
 +    }
 +
 +    // -------------<SOL id="7695a4ce-cca4-4aba-8e04-c5635b2823e3:___cend___" />
 + @Override
 + public boolean checkInputPinsCoverage()
 + {
 + if (in.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select input.");
 + }
 + return true;
 + }
 +    // -------------<LOS id="7695a4ce-cca4-4aba-8e04-c5635b2823e3:___cend___" />
 +</code>
 +
 +<code java Copy.java>
 +    public void execute() 
 +    // -------------<SOL id="86f16d44-83a6-466e-8bc2-eacc21ce4f92:___throw__" />
 +    // -------------<LOS id="86f16d44-83a6-466e-8bc2-eacc21ce4f92:___throw__" />
 +    {
 +        // ---------<SOL id="86f16d44-83a6-466e-8bc2-eacc21ce4f92:___body___" />
 +    Folder source = from.val();
 +        if (source.selected.size() == 0)
 +        {
 +        throw new CommandPreconditionsException("Please, select what to copy.");
 +        }
 +        Folder dest = to.val();
 +        
 +        if (source.equals(dest))
 +        {
 +        throw new CommandPreconditionsException("Please, select different folders.");
 +        }
 +        for (Document d : source.selected.read()) {
 +        if (d instanceof Folder)
 +        if (((Folder) d).isParent(dest))
 +        throw new CommandPreconditionsException("Destination folder is sub folder.");
 +        }
 +        
 +        source.copy(dest);
 +        // ---------<LOS id="86f16d44-83a6-466e-8bc2-eacc21ce4f92:___body___" />
 +    }
 +
 +    // -------------<SOL id="ed4ec470-60cf-4353-a47b-dd0198ebfc4e:___cend___" />
 + @Override
 + public boolean checkInputPinsCoverage()
 + {
 + if (from.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select source.");
 + }
 + if (to.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select destination.");
 + }
 + return true;
 + }
 +    // -------------<LOS id="ed4ec470-60cf-4353-a47b-dd0198ebfc4e:___cend___" />
 +</code>
 +
 +<code java Move.java>
 +    public void execute() 
 +    // -------------<SOL id="d8568511-9904-44d2-adb7-1198405a813a:___throw__" />
 +    // -------------<LOS id="d8568511-9904-44d2-adb7-1198405a813a:___throw__" />
 +    {
 +        // ---------<SOL id="d8568511-9904-44d2-adb7-1198405a813a:___body___" />
 +    Folder source = from.val();
 +    if (source.selected.size() == 0)
 +        {
 +        throw new CommandPreconditionsException("Select item to move!");
 +        }
 +        Folder dest = to.val();
 +        
 +        if (source.equals(dest))
 +        {
 +        throw new CommandPreconditionsException("Select different folders.");
 +        }
 +
 +        for (Document d : source.selected.read()) {
 +        if (d instanceof Folder)
 +        if (((Folder) d).isParent(dest))
 +        throw new CommandPreconditionsException("Destination folder is subfolder!");
 +        }
 +        source.move(dest);
 +        // ---------<LOS id="d8568511-9904-44d2-adb7-1198405a813a:___body___" />
 +    }
 +</code>
 +
 +<code java DeleteSelectedItems.java>
 +    public void execute() 
 +    // -------------<SOL id="821f21b3-fec2-4284-8766-5f6c6fb04ecf:___throw__" />
 +    // -------------<LOS id="821f21b3-fec2-4284-8766-5f6c6fb04ecf:___throw__" />
 +    {
 +        // ---------<SOL id="821f21b3-fec2-4284-8766-5f6c6fb04ecf:___body___" />
 +    Folder f = from.val();
 +        if (f.selected.size() == 0)
 +        {
 +        throw new CommandPreconditionsException("Please, select what to delete.");
 +        }
 +        
 +        f.deleteSelected();
 +        // ---------<LOS id="821f21b3-fec2-4284-8766-5f6c6fb04ecf:___body___" />
 +    }
 +
 +    // -------------<SOL id="0f053b85-f495-44a4-a67e-46789b1de0e0:___cend___" />
 + @Override
 + public boolean checkInputPinsCoverage()
 + {
 + if (from.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select source.");
 + }
 + return true;
 + }
 +</code>
 +
 +<code java ClearSelection.java>
 +    public void execute() 
 +    // -------------<SOL id="75819bb8-dd41-4afa-9079-5754c5754c52:___throw__" />
 +    // -------------<LOS id="75819bb8-dd41-4afa-9079-5754c5754c52:___throw__" />
 +    {
 +        // ---------<SOL id="75819bb8-dd41-4afa-9079-5754c5754c52:___body___" />
 +    Folder f = from.val();
 +        
 +        f.clearSelection();
 +        // ---------<LOS id="75819bb8-dd41-4afa-9079-5754c5754c52:___body___" />
 +    }
 +
 +    // -------------<SOL id="e8667dbc-7a12-4cb0-a211-8c7e20164168:___cend___" />
 + @Override
 + public boolean checkInputPinsCoverage()
 + {
 + if (from.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select source.");
 + }
 + return true;
 + }
 +</code>
 +
 +<code java SelectAll.java>
 +    public void execute() 
 +    // -------------<SOL id="2d4d42a8-18e7-47e4-9e33-6df9eab93ce8:___throw__" />
 +    // -------------<LOS id="2d4d42a8-18e7-47e4-9e33-6df9eab93ce8:___throw__" />
 +    {
 +        // ---------<SOL id="2d4d42a8-18e7-47e4-9e33-6df9eab93ce8:___body___" />
 +    Folder f = from.val();
 +        
 +        f.selectAll();
 +        // ---------<LOS id="2d4d42a8-18e7-47e4-9e33-6df9eab93ce8:___body___" />
 +    }
 +
 +    // -------------<SOL id="f3ef4fb9-baee-4571-88bf-541954bd3aea:___cend___" />
 + @Override
 + public boolean checkInputPinsCoverage()
 + {
 + if (from.val() == null)
 + {
 + throw new CommandPreconditionsException("Please, select source.");
 + }
 + return true;
 + }
 +    // -------------<LOS id="f3ef4fb9-baee-4571-88bf-541954bd3aea:___cend___" />
 +</code>
 +
 +<code java Document.java>
 +    public void rename(Text newTitle) 
 +    // -------------<SOL id="e6dcc7eb-36a0-49a3-bef1-c1d0ad4aedfd:___throw__" />
 +    // -------------<LOS id="e6dcc7eb-36a0-49a3-bef1-c1d0ad4aedfd:___throw__" />
 +    {
 +        // ---------<SOL id="e6dcc7eb-36a0-49a3-bef1-c1d0ad4aedfd:___body___" />
 +    if (newTitle != null && !newTitle.isEmpty())
 +        {
 +        title.set(newTitle);
 +        Folder parent = superItem.val();
 +        if (parent != null)
 +        {
 +        parent.sort();
 +        }
 +        }
 +        // ---------<LOS id="e6dcc7eb-36a0-49a3-bef1-c1d0ad4aedfd:___body___" />
 +    }
 +</code>
 +
 +<code java Folder.java>
 +    public void createFolder(Text title) 
 +    // -------------<SOL id="ae431ac7-2f22-4b1c-aa7a-41c254dac592:___throw__" />
 +    // -------------<LOS id="ae431ac7-2f22-4b1c-aa7a-41c254dac592:___throw__" />
 +    {
 +        // ---------<SOL id="ae431ac7-2f22-4b1c-aa7a-41c254dac592:___body___" />
 +    Folder f = new Folder();
 +        if (title != null && !title.isEmpty())
 +        {
 +        f.title.set(title);
 +        }
 +        else
 +        {
 +        f.title.set(Text.fromString("NewFolder"));
 +        }
 +        subItems.add(f);
 +        
 +        sort();
 +        // ---------<LOS id="ae431ac7-2f22-4b1c-aa7a-41c254dac592:___body___" />
 +    }
 +
 +    
 +    public void createRegularDoc(Text title) 
 +    // -------------<SOL id="321f23ed-cc68-4ee9-92de-7c2a9785b981:___throw__" />
 +    // -------------<LOS id="321f23ed-cc68-4ee9-92de-7c2a9785b981:___throw__" />
 +    {
 +        // ---------<SOL id="321f23ed-cc68-4ee9-92de-7c2a9785b981:___body___" />
 +    RegularDocument file = new RegularDocument();
 +        if (title != null && !title.isEmpty())
 +        {
 +        file.title.set(title);
 +        }
 +        else
 +        {
 +        file.title.set(Text.fromString("NewFile"));
 +        }
 +        subItems.add(file);
 +        
 +        sort();
 +        // ---------<LOS id="321f23ed-cc68-4ee9-92de-7c2a9785b981:___body___" />
 +    }
 +
 +    
 +    public void copy(Folder to) 
 +    // -------------<SOL id="12b7a4b0-502a-44b8-b52f-6833cbbeca58:___throw__" />
 +    // -------------<LOS id="12b7a4b0-502a-44b8-b52f-6833cbbeca58:___throw__" />
 +    {
 +        // ---------<SOL id="12b7a4b0-502a-44b8-b52f-6833cbbeca58:___body___" />
 +    if (this.equals(to)) {
 + throw new RuntimeException("Cannot copy to myself!");
 + }
 +    for (Document selectedDoc : selected.read())
 +        {
 + Document copy = TwoPassCloneManager.clone(selectedDoc, true);
 + to.subItems.add(copy);
 + }
 +        to.sort();
 +        // ---------<LOS id="12b7a4b0-502a-44b8-b52f-6833cbbeca58:___body___" />
 +    }
 +
 +    
 +    public void move(Folder to) 
 +    // -------------<SOL id="619ebdc5-80ff-4fcc-8d0f-fbcce8bc567b:___throw__" />
 +    // -------------<LOS id="619ebdc5-80ff-4fcc-8d0f-fbcce8bc567b:___throw__" />
 +    {
 +        // ---------<SOL id="619ebdc5-80ff-4fcc-8d0f-fbcce8bc567b:___body___" />
 +    if (this.equals(to)) {
 + throw new RuntimeException("Cannot move to myself!");
 + }
 +        for (Document selectedDoc : selected.read())
 +        {
 + this.selected.remove(selectedDoc);
 + this.subItems.remove(selectedDoc);
 + to.subItems.add(selectedDoc);
 + }
 +        to.sort();
 +        // ---------<LOS id="619ebdc5-80ff-4fcc-8d0f-fbcce8bc567b:___body___" />
 +    }
 +
 +    
 +    public void deleteSelected() 
 +    // -------------<SOL id="846993a8-efb5-4fc4-8fbe-c770f18e9f9c:___throw__" />
 +    // -------------<LOS id="846993a8-efb5-4fc4-8fbe-c770f18e9f9c:___throw__" />
 +    {
 +        // ---------<SOL id="846993a8-efb5-4fc4-8fbe-c770f18e9f9c:___body___" />
 +    List<Document> toDelete = selected.read();
 +    selected.clear();
 +    for (Document document : toDelete)
 +    {
 + document.destroy();
 + }
 +   
 + sort();
 +        // ---------<LOS id="846993a8-efb5-4fc4-8fbe-c770f18e9f9c:___body___" />
 +    }
 +
 +    
 +    public void clearSelection() 
 +    // -------------<SOL id="67c1ba1a-2ed4-4205-8de1-016a7e4237d1:___throw__" />
 +    // -------------<LOS id="67c1ba1a-2ed4-4205-8de1-016a7e4237d1:___throw__" />
 +    {
 +        // ---------<SOL id="67c1ba1a-2ed4-4205-8de1-016a7e4237d1:___body___" />
 +    selected.clear();
 +        // ---------<LOS id="67c1ba1a-2ed4-4205-8de1-016a7e4237d1:___body___" />
 +    }
 +
 +    
 +    public void selectAll() 
 +    // -------------<SOL id="55b2c057-50b4-4884-8528-07c2f09a904f:___throw__" />
 +    // -------------<LOS id="55b2c057-50b4-4884-8528-07c2f09a904f:___throw__" />
 +    {
 +        // ---------<SOL id="55b2c057-50b4-4884-8528-07c2f09a904f:___body___" />
 +    List<Document> initiallySelected = selected.read();
 +        for (Document subItem : subItems.read())
 +        {
 + if (!initiallySelected.contains(subItem))
 + {
 + selected.add(subItem);
 + }
 + }
 +        // ---------<LOS id="55b2c057-50b4-4884-8528-07c2f09a904f:___body___" />
 +    }
 +
 +    
 +    public void sort() 
 +    // -------------<SOL id="41a3b82a-1fda-41fe-8b54-2a3d739b20d2:___throw__" />
 +    // -------------<LOS id="41a3b82a-1fda-41fe-8b54-2a3d739b20d2:___throw__" />
 +    {
 +        // ---------<SOL id="41a3b82a-1fda-41fe-8b54-2a3d739b20d2:___body___" />
 +    List<Document> folders = new ArrayList<Document>();
 +        List<Document> files = new ArrayList<Document>();
 + for (Document document : subItems.read()) {
 + if (document instanceof Folder) {
 + folders.add(document);
 + } else {
 + files.add(document);
 + }
 + }
 +        
 +        Document.DocumentComparator comparator = new Document.DocumentComparator();
 +        Collections.sort(folders, comparator);
 +        Collections.sort(files, comparator);
 +        
 +        List<Document> allDocuments = folders;
 +        allDocuments.addAll(files);
 +        subItems.set(allDocuments);
 +        // ---------<LOS id="41a3b82a-1fda-41fe-8b54-2a3d739b20d2:___body___" />
 +    }
 +
 +    // -------------<SOL id="404cd1fd-f92a-4579-9169-3bb45171030d:___cend___" />
 + public boolean isParent(Document d)
 + {
 + for (Document subItem : subItems.read())
 + {
 + if (subItem.equals(d))
 + {
 + return true;
 + }
 + if (subItem instanceof Folder)
 + {
 + Folder subFolder = (Folder)subItem;
 + if (subFolder.isParent(d))
 + {
 + return true;
 + }
 + }
 + }
 + return false;
 + }
 +
 + /**
 + * In megabytes.
 + * @return
 + */
 + public double getSize()
 + {
 + return getSizeInBytes() / (1024.*1024.);
 + }
 +
 + /**
 + * In bytes.
 + * @return
 + */
 + public long getSizeInBytes()
 + {
 + long total = 0;
 + for (Document subItem : subItems.read())
 + {
 + if (subItem instanceof RegularDocument)
 + {
 + RegularDocument rd = (RegularDocument)subItem;
 + File file = rd.file.val();
 + if (file != null)
 + {
 + total = total + file.getFileSize();
 + }
 + }
 + else if (subItem instanceof PictureFromGallery)
 + {
 + PictureFromGallery pfg = (PictureFromGallery)subItem;
 + Picture picture = pfg.picture.val();
 + if (picture != null)
 + {
 + total = total + picture.getFileSize();
 + }
 + }
 + else if (subItem instanceof Folder)
 + {
 + Folder f = (Folder)subItem;
 + total = total + f.getSizeInBytes();
 + }
 + }
 + return total;
 + }
 +    // -------------<LOS id="404cd1fd-f92a-4579-9169-3bb45171030d:___cend___" />
 +</code>
 ===== GUI Code ===== ===== GUI Code =====
 <code java> <code java>
-//...+package rs.sol.sampleapps; 
 + 
 +import rs.sol.sampleapps.commands.ClearSelection; 
 +import rs.sol.sampleapps.commands.Copy; 
 +import rs.sol.sampleapps.commands.CreateFolder; 
 +import rs.sol.sampleapps.commands.CreateRegularDocument; 
 +import rs.sol.sampleapps.commands.DeleteSelectedItems; 
 +import rs.sol.sampleapps.commands.Move; 
 +import rs.sol.sampleapps.commands.RenameDocument; 
 +import rs.sol.sampleapps.commands.SelectAll; 
 +import rs.sol.sampleapps.gui.GUIBreadCrumbsSample; 
 +import rs.sol.sampleapps.gui.GUIFileSystemSample; 
 +import rs.sol.soloist.helpers.init.DefaultContextInit; 
 +import rs.sol.soloist.helpers.init.Initializer; 
 +import rs.sol.soloist.helpers.init.InitializerFailedException; 
 +import rs.sol.soloist.server.builtindomains.builtindatatypes.Boolean; 
 +import rs.sol.soloist.server.builtindomains.builtindatatypes.Text; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIApplicationComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIButtonComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUICommandComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIContainerComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUILabelComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.GUIPanelComponent; 
 +import rs.sol.soloist.server.guiconfiguration.components.PerformImmediately; 
 +import rs.sol.soloist.server.guiconfiguration.construction.GUIComponent; 
 +import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding; 
 +import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIElementComponent; 
 +import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIInput; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIBooleanFilter; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIBufferComponent; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIFindAllInstancesSAPComponent; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUINullFilter; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUITransformerComponent; 
 +import rs.sol.soloist.server.guiconfiguration.style.GUIContext; 
 +import rs.sol.soloist.server.guiconfiguration.style.GUIObjectSetting; 
 +import rs.sol.soloist.server.guiconfiguration.style.GUITextFeature; 
 +import rs.sol.soloist.server.server.SoloistServiceServlet; 
 +import rs.sol.soloist.server.uml.concepts.IElement; 
 +import rs.sol.soloist.server.uml.concepts.runtime.ISlot; 
 + 
 +public enum FileSystem implements Initializer{ 
 + 
 + INSTANCE; 
 +  
 + public static Copy copy; 
 + public static Move move; 
 + public static DeleteSelectedItems deleteSelectedItems; 
 + public static ClearSelection clearSelection; 
 + public static SelectAll selectAll; 
 + public static CreateFolder createFolder; 
 + public static CreateRegularDocument createRegularDocument; 
 + public static RenameDocument rename; 
 +  
 + @Override 
 + public void init() throws InitializerFailedException 
 +
 + GUIApplicationComponent page = new GUIApplicationComponent(); 
 + page.setName("FileSystem");  
 + SoloistServiceServlet.registerApplication(page); 
 + GUIContext context = createContextAndStyles(); 
 + page.setContext(context); 
 +  
 + GUIPanelComponent root = GUIPanelComponent.createFlow(page); 
 +  
 + GUILabelComponent title = GUILabelComponent.create(root, "File System"); 
 + title.setStyle("titleStyle"); 
 +  
 + GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root); 
 + topPanel.setStyle("topPanel"); 
 + 
 + GUIFindAllInstancesSAPComponent allPersons = GUIFindAllInstancesSAPComponent.create(root, Person.CLASSIFIER); 
 + GUILabelComponent.create(topPanel, "Choose person:").setStyle("margin3"); 
 + GUIInput suggestBox = GUIInput.createSuggest(topPanel); 
 + suggestBox.setStyle("margin3"); 
 + GUIComponentBinding.create(allPersons.opValue(), suggestBox.ipCollection()); 
 +  
 + copy = new Copy(); 
 + move = new Move(); 
 + deleteSelectedItems = new DeleteSelectedItems(); 
 + clearSelection = new ClearSelection(); 
 + selectAll = new SelectAll(); 
 + createFolder = new CreateFolder(); 
 + createRegularDocument = new CreateRegularDocument(); 
 + rename = new RenameDocument(); 
 +  
 + GUIPanelComponent fileSystemPanel = GUIPanelComponent.createFlow(topPanel); 
 + fileSystemPanel.setStyle("fileSystemRootPanel"); 
 +  
 + GUITransformerComponent gtc = GUITransformerComponent.createSlotValue(fileSystemPanel, Person.PROPERTIES.rootFolder); 
 + GUIComponentBinding.create(suggestBox.opValue(), gtc.ipInput()); 
 +  
 + GUIBufferComponent leftBufferWithRootFolder = GUIBufferComponent.create(fileSystemPanel, false, (IElement)null); // initially empty 
 + GUIBufferComponent rightBufferWithRootFolder = GUIBufferComponent.create(fileSystemPanel, false, (IElement)null); // initially empty 
 + GUIComponentBinding.create(gtc.opOutput(), leftBufferWithRootFolder.ipInput()); // first fill the buffer 
 + GUIComponentBinding.create(gtc.opOutput(), rightBufferWithRootFolder.ipInput()); // first fill the buffer 
 + GUIComponentBinding.create(gtc.opOutput(), leftBufferWithRootFolder.ipSend()); // then tell it to send 
 + GUIComponentBinding.create(gtc.opOutput(), rightBufferWithRootFolder.ipSend()); // then tell it to send 
 +  
 + GUIPanelComponent left = GUIPanelComponent.createFlow(fileSystemPanel); 
 + left.setStyle("floatL"); 
 + GUIPanelComponent buttonColumn = GUIPanelComponent.createFlow(fileSystemPanel); 
 + buttonColumn.setStyle("buttonColumn"); 
 + GUIPanelComponent right = GUIPanelComponent.createFlow(fileSystemPanel); 
 + right.setStyle("floatR"); 
 +  
 + GUIBreadCrumbsSample leftBread = new GUIBreadCrumbsSample(); 
 + left.add(leftBread); 
 + GUIFileSystemSample leftBrowser = new GUIFileSystemSample(); 
 + leftBrowser.isLeft.set(Boolean.TRUE); 
 + fileBrowserHeadingFragment(left, leftBread.opRelay1()); 
 + left.add(leftBrowser); 
 + GUIComponentBinding.create(leftBufferWithRootFolder.opOutput(), leftBread.ipElement()); 
 + GUIComponentBinding.create(leftBufferWithRootFolder.opOutput(), leftBrowser.ipElement()); 
 + GUIComponentBinding.create(leftBread.opRelay2(), leftBrowser.ipElement()); 
 + GUIComponentBinding.create(leftBrowser.opRelay2(), leftBread.ipElement()); 
 + GUIComponentBinding.create(left.opRelay2(), leftBrowser.ipRefreshContents()); 
 +  
 + GUIBreadCrumbsSample rightBread = new GUIBreadCrumbsSample(); 
 + right.add(rightBread); 
 + GUIFileSystemSample rightBrowser = new GUIFileSystemSample(); 
 + rightBrowser.isLeft.set(Boolean.FALSE); 
 + fileBrowserHeadingFragment(right, rightBread.opRelay1()); 
 + right.add(rightBrowser); 
 + GUIComponentBinding.create(rightBufferWithRootFolder.opOutput(), rightBread.ipElement()); 
 + GUIComponentBinding.create(rightBufferWithRootFolder.opOutput(), rightBrowser.ipElement()); 
 + GUIComponentBinding.create(rightBread.opRelay2(), rightBrowser.ipElement()); 
 + GUIComponentBinding.create(rightBrowser.opRelay2(), rightBread.ipElement()); 
 + GUIComponentBinding.create(right.opRelay2(), rightBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(right.opRelay2(), leftBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(left.opRelay2(), rightBrowser.ipRefreshContents()); 
 +  
 + // connecting browsers 
 + GUIComponentBinding.create(leftBrowser.opRelay2(), leftBrowser.ipElement()); 
 + GUIComponentBinding.create(rightBrowser.opRelay2(), rightBrowser.ipElement()); 
 +  
 + GUIComponentBinding.create(leftBread.opRelay2(), leftBread.ipElement()); 
 + GUIComponentBinding.create(rightBread.opRelay2(), rightBread.ipElement()); 
 + // end connecting browsers 
 +  
 + GUIButtonComponent copyLTR = GUIButtonComponent.create(buttonColumn, " ", new Copy()); 
 + copyLTR.setTooltip("Copy left to right"); 
 + copyLTR.setStyle("copyLTR"); 
 + GUIComponentBinding.create(leftBread.opRelay1(), copyLTR, Copy.PROPERTIES.from); 
 + GUIComponentBinding.create(rightBread.opRelay1(), copyLTR, Copy.PROPERTIES.to); 
 + 
 + GUIButtonComponent moveLTR = GUIButtonComponent.create(buttonColumn, " ", new Move()); 
 + moveLTR.setTooltip("Move left to right"); 
 + moveLTR.setStyle("moveLTR"); 
 + GUIComponentBinding.create(leftBread.opRelay1(), moveLTR, Move.PROPERTIES.from); 
 + GUIComponentBinding.create(rightBread.opRelay1(), moveLTR, Move.PROPERTIES.to); 
 +  
 + GUIButtonComponent copyRTL = GUIButtonComponent.create(buttonColumn, " ", new Copy()); 
 + copyRTL.setTooltip("Copy right to left"); 
 + copyRTL.setStyle("copyRTL"); 
 + GUIComponentBinding.create(rightBread.opRelay1(), copyRTL, Copy.PROPERTIES.from); 
 + GUIComponentBinding.create(leftBread.opRelay1(), copyRTL, Copy.PROPERTIES.to); 
 +  
 + GUIButtonComponent moveRTL = GUIButtonComponent.create(buttonColumn, " ", new Move()); 
 + moveRTL.setTooltip("Move right to left"); 
 + moveRTL.setStyle("moveRTL"); 
 + GUIComponentBinding.create(rightBread.opRelay1(), moveRTL, Move.PROPERTIES.from); 
 + GUIComponentBinding.create(leftBread.opRelay1(), moveRTL, Move.PROPERTIES.to); 
 +  
 + GUIComponentBinding.create(copyLTR.opCommandExecuted(), leftBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(copyLTR.opCommandExecuted(), rightBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(moveLTR.opCommandExecuted(), leftBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(moveLTR.opCommandExecuted(), rightBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(copyRTL.opCommandExecuted(), leftBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(copyRTL.opCommandExecuted(), rightBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(moveRTL.opCommandExecuted(), leftBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(moveRTL.opCommandExecuted(), rightBrowser.ipRefreshContents()); 
 +  
 + GUINullFilter leftNullFilter = GUINullFilter.create(fileSystemPanel); 
 + GUIComponentBinding.create(leftBread.opRelay1(), leftNullFilter.ipInput()); 
 + GUINullFilter rightNullFilter = GUINullFilter.create(fileSystemPanel); 
 + GUIComponentBinding.create(rightBread.opRelay1(), rightNullFilter.ipInput()); 
 + GUIComponentBinding.create(leftNullFilter.opYes(), leftBufferWithRootFolder.ipSend()); 
 + GUIComponentBinding.create(rightNullFilter.opYes(), rightBufferWithRootFolder.ipSend()); 
 +  
 + GUIComponentBinding.create(leftBrowser.opRelay1(), leftBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(leftBrowser.opRelay1(), rightBrowser.ipRefreshContents()); 
 +  
 + GUIComponentBinding.create(rightBrowser.opRelay1(), rightBrowser.ipRefreshContents()); 
 + GUIComponentBinding.create(rightBrowser.opRelay1(), leftBrowser.ipRefreshContents()); 
 +
 + 
 + private void fileBrowserHeadingFragment(GUIPanelComponent rootPanel, ISlot<?> folder) 
 +
 + //heading 
 +    GUIPanelComponent heading = GUIPanelComponent.createFlow(rootPanel); 
 +    heading.setStyle("fileBrowserHeading"); 
 +     
 +    GUIInput selectionCheckbox = GUIInput.createField(heading, Boolean.CLASSIFIER); 
 +    selectionCheckbox.addInitialValue(Boolean.FALSE); 
 +    selectionCheckbox.setLowerBound(1); 
 +    selectionCheckbox.setTooltip("Select/Deselect All"); 
 +     
 +    GUICommandComponent selectCmd = GUICommandComponent.create(heading, FileSystem.selectAll, PerformImmediately.NOTHING); 
 +    GUICommandComponent clearSelectionCmd = GUICommandComponent.create(heading, FileSystem.clearSelection, PerformImmediately.NOTHING); 
 +    GUIComponentBinding.create(folder, selectCmd, SelectAll.PROPERTIES.from); 
 +    GUIComponentBinding.create(folder, clearSelectionCmd, ClearSelection.PROPERTIES.from); 
 +     
 +    GUIBooleanFilter gbf = GUIBooleanFilter.create(heading); 
 +     
 +    FileSystem.missFirstValueLogic(heading, selectionCheckbox, gbf, gbf.ipInput()); 
 +     
 +    GUIComponentBinding.create(gbf.opYes(), selectCmd.ipClick()); 
 +    GUIComponentBinding.create(gbf.opNo(), clearSelectionCmd.ipClick()); 
 +     
 +    GUIButtonComponent delete = GUIButtonComponent.create(heading, " ", FileSystem.deleteSelectedItems); 
 +    delete.setTooltip("Delete"); 
 +    delete.setStyle("delBtn"); 
 +    delete.setConfirmationRequired(true); 
 +    delete.setConfirmationMessage("Delete?"); 
 +    GUIComponentBinding.create(folder, delete, DeleteSelectedItems.PROPERTIES.from); 
 +     
 +    GUIButtonComponent newDocument = GUIButtonComponent.create(heading, " ", FileSystem.createRegularDocument); 
 +    newDocument.setTooltip("Create new file"); 
 +    newDocument.setStyle("multiUploadAddMoreBtn"); 
 +    GUIComponentBinding.create(folder, newDocument, CreateRegularDocument.PROPERTIES.in); 
 +    GUIButtonComponent newFolder = GUIButtonComponent.create(heading, " ", FileSystem.createFolder); 
 +    newFolder.setTooltip("Create new folder"); 
 +    newFolder.setStyle("addFolder"); 
 +    GUIComponentBinding.create(folder, newFolder, CreateFolder.PROPERTIES.in); 
 +    GUIInput newName = GUIInput.createField(heading, Text.CLASSIFIER); 
 +    newName.setTooltip("Name"); 
 +    GUIComponentBinding.create(newName.opValue(), newDocument, CreateRegularDocument.PROPERTIES.title); 
 +    GUIComponentBinding.create(newName.opValue(), newFolder, CreateFolder.PROPERTIES.title); 
 +     
 +    GUIComponentBinding.create(delete.opCommandExecuted(), rootPanel.ipRelay2()); 
 +    GUIComponentBinding.create(newFolder.opCommandExecuted(), rootPanel.ipRelay2()); 
 +    GUIComponentBinding.create(newDocument.opCommandExecuted(), rootPanel.ipRelay2()); 
 +
 +  
 + private GUIContext createContextAndStyles() 
 +
 + GUIContext context = new GUIContext(); 
 + DefaultContextInit.getRoot().addContext(context); 
 +  
 + GUIObjectSetting folder = GUIObjectSetting.create(context, Folder.CLASSIFIER); 
 + GUITextFeature.createFixedName(folder, ""); 
 +  
 + GUIObjectSetting regularDocument = GUIObjectSetting.create(context, RegularDocument.CLASSIFIER); 
 + GUITextFeature.createFixedName(regularDocument, ""); 
 +  
 + return context; 
 +
 +  
 + public static void missFirstValueLogic(GUIContainerComponent panelForNonVisuals, GUIElementComponent source, GUIComponent destComp, ISlot<?> destSlot) 
 +
 + destComp.setEnabled(false); 
 +  
 + GUIComponentBinding.create(source.opValue(), destSlot); // fisrt 
 + GUIBufferComponent enableBuffer = GUIBufferComponent.create(panelForNonVisuals, false, Boolean.TRUE); 
 + GUIComponentBinding.create(enableBuffer.opOutput(), destComp.ipEnabled()); 
 + GUIComponentBinding.create(source.opValue(), enableBuffer.ipSend()); // second 
 +
 +
 +</code> 
 + 
 +<code java GUIFileSystemSample.java> 
 +    @Override 
 +    protected GUIContainerComponent getDynamicContents(IElement el) 
 +    { 
 +    GUIPanelComponent rootPanel = GUIPanelComponent.createFlow(null); 
 +    rootPanel.setStyle("fileBrowser"); 
 +     
 +    Folder folder = (Folder) el; 
 +    if (folder == null) 
 +    return rootPanel; 
 +     
 +    try 
 +    { 
 +    folder.title.val(); // We first check whether this object exist. 
 +    } 
 +    catch(GeneralActionExecutionException gaee) 
 +    { 
 +    return rootPanel; // If the object does not exist, we just return empty panel. 
 +    } 
 +     
 +    GUIBufferComponent folderBuf = GUIBufferComponent.create(rootPanel, true, folder); 
 +     
 +    //Items 
 +    GUIPanelComponent itemsTable = GUIPanelComponent.createTable(rootPanel); 
 +    int row = 0; 
 +    for (Document item : folder.subItems.read()) { 
 +    int col = 0; 
 +    GUIBufferComponent itemBuf = GUIBufferComponent.create(rootPanel, true, item); 
 +    GUIEdit select = GUIEdit.createList(itemsTable, Folder.PROPERTIES.selected); 
 +    select.setLayoutData(TableLayoutData.create(row, col++)); 
 +    GUIComponentBinding.create(itemBuf.opOutput(), select.ipCollection()); 
 +    GUIComponentBinding.create(folderBuf.opOutput(), select.ipElement()); 
 + 
 +    GUIButtonComponent edit = GUIButtonComponent.create(itemsTable, " ", TableLayoutData.create(row, col++)); 
 +    edit.setStyle("editName"); 
 +    edit.setTooltip("Rename"); 
 + 
 +    GUIPanelComponent nameWrap = GUIPanelComponent.createFlow(itemsTable); 
 +    if (item instanceof Folder) 
 +    nameWrap.setRowColumn(row, col++, 1, 4); //chrome likes colspan 4  
 +    else 
 +    nameWrap.setRowColumn(row, col++); 
 + 
 +    GUIButtonComponent buttonLink = GUIButtonComponent.createLink(nameWrap, item.title.val().toString()); 
 +    if (item instanceof RegularDocument)  
 +    buttonLink.setStyle("#fileLink"); 
 +    else 
 +    buttonLink.setStyle("#folderLink"); 
 + 
 +    if (item instanceof Folder) // Only for folders we will do navigation through the hierarchy and folder size. 
 +    { 
 +    GUIBufferComponent b1 = GUIBufferComponent.create(rootPanel, false, item); 
 +        GUIComponentBinding.create(b1.opOutput(), this.ipRelay2()); 
 +        GUIComponentBinding.create(buttonLink.opClick(), b1.ipSend()); 
 +         
 +        GUILabelComponent.create(nameWrap, FormattingUtility.formatReal(Real.valueOf(((Folder)item).getSize())) + "MB"); 
 +    } 
 +     
 +    GUIInput nameInput = GUIInput.createField(nameWrap, Text.CLASSIFIER); 
 +    nameInput.addInitialValue(item.title.val()); 
 +    nameInput.setStyle("gwt-TextBox-invisible"); 
 +    GUICommandComponent rename = GUICommandComponent.create(nameWrap, FileSystem.rename, PerformImmediately.NOTHING); 
 +    GUIComponentBinding.create(itemBuf.opOutput(), rename, RenameDocument.PROPERTIES.document); 
 +    GUIComponentBinding.create(nameInput.opValue(), rename, RenameDocument.PROPERTIES.newTitle); 
 +     
 +    GUIRelayComponent clickRelay = GUIRelayComponent.create(nameWrap); 
 +    FileSystem.missFirstValueLogic(nameWrap, nameInput, clickRelay, clickRelay.ipRelay()); 
 +    GUIComponentBinding.create(clickRelay.opRelay(), rename.ipClick()); 
 +     
 +    GUIBufferComponent nullBuffer = GUIBufferComponent.create(rootPanel, false, (IElement)null); 
 +        GUIComponentBinding.create(nullBuffer.opOutput(), this.ipRelay1()); 
 +        GUIComponentBinding.create(rename.opCommandExecuted(), nullBuffer.ipSend()); 
 +     
 +    GUIBufferComponent showEditor = GUIBufferComponent.create(nameWrap, false, Text.fromString("invisible")); 
 +    GUIBufferComponent showLink = GUIBufferComponent.create(nameWrap, false, Text.fromString("invisible")); 
 +    GUIComponentBinding.create(edit.opClick(), showEditor.ipSend()); 
 +    GUIComponentBinding.create(rename.opCommandExecuted(), showLink.ipSend()); 
 +    GUIComponentBinding.create(showEditor.opOutput(), nameInput.ipRemoveStyle()); 
 +    GUIComponentBinding.create(showEditor.opOutput(), buttonLink.ipAddStyle()); 
 +    GUIComponentBinding.create(showLink.opOutput(), nameInput.ipAddStyle()); 
 +    GUIComponentBinding.create(showLink.opOutput(), buttonLink.ipRemoveStyle()); 
 +     
 +    if (item instanceof RegularDocument) { 
 +    GUIPanelComponent fileUploader = GUIEdit.createFile(itemsTable, RegularDocument.PROPERTIES.file, true, true); 
 +    GUIComponentBinding.create(itemBuf.opOutput(), fileUploader.ipRelay1()); 
 +    fileUploader.setRowColumn(row, col++); 
 +     
 +    GUIEdit.getBrowseButton(fileUploader).setStyle("#browse" + (isLeft.val().toBoolean() ? "L" : "R") + row); 
 +    GUIHTMLComponent browse = GUIHTMLComponent.create(itemsTable, "<input type=\"button\" class=\"gwt-Button browseFolder\" onclick=\"triggerBrowse('browse" + (isLeft.val().toBoolean() ? "L" : "R") + row + "');\">"); 
 +    browse.setLayoutData(TableLayoutData.create(row, col++)); 
 +    browse.setTooltip("Browse"); 
 +    } 
 +     
 +    row++; 
 +    } 
 +     
 +    return rootPanel; 
 +    } 
 +</code> 
 + 
 +<code java GUIBreadCrumbsSample.java> 
 +    @Override 
 +    protected GUIContainerComponent getDynamicContents(IElement el) 
 +    { 
 +    GUIPanelComponent rootPanel = GUIPanelComponent.createFlow(null); 
 +    rootPanel.setStyle("filesystem_breadcrumb"); 
 +     
 +    Folder f = (Folder)el; 
 +    if (f == null) 
 +    { 
 +    return rootPanel; 
 +    } 
 +     
 +    try 
 +    { 
 +    f.title.val(); // We first check whether this object exist. 
 +    } 
 +    catch(GeneralActionExecutionException gaee) 
 +    { 
 +    GUIBufferComponent nullBuffer = GUIBufferComponent.create(rootPanel, true, (IElement)null); 
 +        GUIComponentBinding.create(nullBuffer.opOutput(), this.ipRelay1()); 
 +    return rootPanel; // If the object does not exist, we just return empty panel. 
 +    } 
 +     
 +    GUILabelComponent thisFolder = GUILabelComponent.create(rootPanel, getFolderName(f)); 
 +    thisFolder.setStyle("displayInline"); 
 +     
 +    Folder current = f.superItem.val(); 
 +    while (current != null) 
 +    { 
 +    GUILabelComponent separator = new GUILabelComponent(); 
 +    separator.setLabel("/"); 
 +    separator.setStyle("displayInline"); 
 +    rootPanel.addFirst(separator); 
 +     
 +    GUIButtonComponent link = new GUIButtonComponent(); 
 +    link.setDisplayAsLink(true); 
 +    link.setText(getFolderName(current)); 
 +    link.setStyle("displayInline"); 
 +    rootPanel.addFirst(link); 
 +     
 +    GUIBufferComponent buffer = GUIBufferComponent.create(rootPanel, false, current); 
 +    GUIComponentBinding.create(buffer.opOutput(), this.ipRelay2()); 
 +    GUIComponentBinding.create(link.opClick(), buffer.ipSend()); 
 +     
 +    current = current.superItem.val(); 
 +    } 
 +     
 +    GUIBufferComponent currentFolderBuffer = GUIBufferComponent.create(rootPanel, true, f); 
 +    GUIComponentBinding.create(currentFolderBuffer.opOutput(), this.ipRelay1()); 
 +     
 +    return rootPanel; 
 +    } 
 + 
 + private String getFolderName(Folder f) 
 +
 + return f.superItem.val() == null ? getRootFolderName(f) : f.title.val().toString(); 
 +
 +     
 +    private String getRootFolderName(Folder f) 
 +    { 
 +    if (f.owner.val() != null) 
 +    { 
 +    return f.owner.val().name.val().toString(); 
 +    } 
 +    return ""; // this shuold never happen 
 +    } 
 +</code> 
 + 
 +<code javascript extension.js> 
 +function triggerBrowse(id) { 
 + var doc = document.getElementById(id); 
 + var file = doc.getElementsByTagName("input").item(0); 
 + file.click(); 
 +}
 </code> </code>
Print/export