Ticket #2228: closeMasterAccesses.patch

File closeMasterAccesses.patch, 22.0 KB (added by mira, 15 years ago)
  • src/main/java/org/sophie2/main/app/commons/app/DocumentsLogic.java

    ### Eclipse Workspace Patch 1.0
    #P org.sophie2.main.app.commons
     
    114114                                        mainWindow.currentDocument().set(null); 
    115115                                         
    116116                                } 
    117                                  
    118117                                docView.getAccess().close(); 
    119118                        }        
    120119                         
  • src/main/java/org/sophie2/main/app/commons/util/SaveDocUtil.java

     
    99import org.sophie2.base.model.resources.r4.access.AccessOptions; 
    1010import org.sophie2.base.model.resources.r4.access.BaseResourceAccess; 
    1111import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
     12import org.sophie2.base.model.resources.r4.access.ResourceLocator; 
    1213import org.sophie2.base.model.resources.r4.access.StoredResourceAccess; 
    1314import org.sophie2.main.app.commons.app.AppMainWindow; 
    1415import org.sophie2.main.app.commons.book.BookDocView; 
     
    9091                file = FileDialogInput.appendFileExtension(file, FileDialogInput.BOOK_FILTER); 
    9192 
    9293                final ResourceRefR4 fileRef = ResourceRefR4.make(file); 
     94                AppMainWindow mainWindow = AppViewUtil.findMainWindow(bookDocView); 
     95                ResourceLocator locator = mainWindow.locator().get(); 
    9396                try { 
    94                         if (!access.getRef().equals(fileRef)) { 
    95 //                              if (ResourceFilesUtil.hasFileDirectory(bookDocView.model().get())) { 
    96 //                                      ResourceFilesUtil.copyResourceDir( 
    97 //                                                      access.getRef().getLocation(), fileRef.getLocation()); 
    98 //                              } 
    99                                  
    100                                 AppMainWindow mainWindow = AppViewUtil.findMainWindow(bookDocView); 
    101                                 StoredResourceAccess fileAccess = (StoredResourceAccess) mainWindow.locator().get().create( 
    102                                                 fileRef, AccessOptions.DEFAULT_ACCESS_OPTIONS, 
     97                        StoredResourceAccess fileAccess;  
     98                        if (access.getRef().equals(fileRef)) { 
     99                                fileAccess = ((StoredResourceAccess) access); 
     100                        } else { 
     101                                fileAccess = (StoredResourceAccess) locator.create( 
     102                                                fileRef, AccessOptions.DEFAULT_ACCESS_OPTIONS.modifyViewId(), 
    103103                                                ((BaseResourceAccess) bookDocView.getAccess()).cloneHeadRevision()); 
    104                                 fileAccess.save(null); 
    105                                 bookDocView.reopen(fileAccess); 
    106                         } else { 
    107                                 ((StoredResourceAccess) access).save(null); 
     104                                if (fileAccess == null) { 
     105                                        DialogUtils.showErrorDialog(bookDocView.swingComponent().get(), 
     106                                                        "The resource at "+ fileRef + " is currently in use.",  
     107                                                        "Could not save book"); 
     108                                        return false; 
     109                                } 
    108110                        } 
     111                        fileAccess.save(null); 
     112                        bookDocView.reopen(fileAccess); 
     113                         
    109114                } catch (IOException e) { 
    110115                        DialogUtils.showExceptionDialog(bookDocView.swingComponent().get(), 
    111                                         e, "Couldn't Save Book"); 
     116                                        e, "Couldn't Save Book At The Given Location."); 
    112117                        return false; 
    113                 } 
     118                }  
    114119                return true; 
    115120        } 
     121 
    116122} 
  • src/main/java/org/sophie2/main/func/servers/logic/ServersTabLogic.java

    #P org.sophie2.main.func.servers
     
    33import java.awt.Component; 
    44import java.io.File; 
    55import java.io.IOException; 
     6import java.util.ArrayList; 
     7import java.util.List; 
    68 
    79import org.sophie2.base.commons.util.Mapper; 
    810import org.sophie2.base.connectivity.resources.DelegatingServerAccess; 
    911import org.sophie2.base.connectivity.resources.ResourceDirectoryH; 
    1012import org.sophie2.base.dialogs.DialogInput; 
    1113import org.sophie2.base.dialogs.DialogManager; 
     14import org.sophie2.base.layout.model.DocView; 
    1215import org.sophie2.base.menus.MenuItem; 
    1316import org.sophie2.base.model.resources.r4.LocationPrefix; 
    1417import org.sophie2.base.model.resources.r4.ResourceRefList; 
     
    2730import org.sophie2.core.mvc.SortKey; 
    2831import org.sophie2.core.mvc.events.EventR3; 
    2932import org.sophie2.main.app.commons.app.AppMainWindow; 
     33import org.sophie2.main.app.commons.app.ResourceDocView; 
    3034import org.sophie2.main.app.commons.book.BookDocView; 
    3135import org.sophie2.main.app.commons.util.AppViewUtil; 
    3236import org.sophie2.main.dialogs.input.DialogUtils; 
     
    7983                        AccountH account = palette.selectedConnection().get().account().get(); 
    8084                        if (palette.isConnected(account)) { 
    8185                                if (palette.disconnect(account)) { 
     86                                        //Close all views to the server accesses that we just closed. 
     87                                        AppMainWindow mainWindow = AppViewUtil.findMainWindow(palette); 
     88                                        List<DocView> docViews = mainWindow.documents().get(); 
     89                                        List<DocView> toRemove = new ArrayList<DocView>(); 
     90                                        for (DocView docView : docViews) { 
     91                                                if (docView instanceof ResourceDocView) { 
     92                                                        ResourceAccess access = ((ResourceDocView)docView).getAccess(); 
     93                                                        if (access.isClosed()) { 
     94                                                                if (mainWindow.currentDocument().get() == docView) { 
     95                                                                        mainWindow.currentDocument().set(null); 
     96                                                                } 
     97                                                                toRemove.add(docView); 
     98                                                        } 
     99                                                } 
     100                                        } 
     101                                        mainWindow.documents().get().removeAll(toRemove); 
    82102                                        DialogManager.get().showDialog( 
    83103                                                        new MessageDialogInput(null, 
    84104                                                                        "Succesfully disconected.")); 
     
    203223                                        int accountIndex = connectionsPalette.accounts().get().indexOf( 
    204224                                                        account); 
    205225                                        connectionsPalette.accounts().remove(accountIndex); 
     226                                        AccountUtil.deleteAccount(account); 
    206227                                        account.getAccess().close(); 
    207                                         AccountUtil.deleteAccount(account); 
    208228                                } 
    209229                        } 
    210230                        return true; 
  • src/main/java/org/sophie2/main/app/menus/file/FileMenuLogic.java

    #P org.sophie2.main.app.menus
     
    194194 
    195195                        AppMainWindow mainWindow = AppViewUtil.findMainWindow(bookDocView); 
    196196                        StoredResourceAccess fileAccess = (StoredResourceAccess) mainWindow.locator().get().create( 
    197                                         ResourceRefR4.make(file), AccessOptions.DEFAULT_ACCESS_OPTIONS, 
     197                                        ResourceRefR4.make(file), AccessOptions.DEFAULT_ACCESS_OPTIONS.modifyViewId(), 
    198198                                        bookDocView.getAccess().getHead()); 
    199199 
    200200                        try { 
  • src/main/java/org/sophie2/main/func/text/model/TailTextFrameH.java

    #P org.sophie2.main.func.text
     
    33import org.sophie2.base.commons.util.ImmMap; 
    44import org.sophie2.base.commons.util.ImmMap.ImmEntry; 
    55import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    6 import org.sophie2.base.model.resources.r4.access.AccessOptions; 
    76import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    87import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    98import org.sophie2.main.app.commons.book.BookView; 
     
    4443                assert bookView != null : "Cannot get the head helper in a null bookView."; 
    4544 
    4645                ResourceAccess headAccess =  
    47                         bookView.getAccess().open(getHeadReference(bookView.getAccess().getRef()), AccessOptions.DEFAULT_ACCESS_OPTIONS); 
     46                        bookView.getAccess().open(getHeadReference(bookView.getAccess().getRef()), null); 
    4847         
    4948                return ResourceH.getHelper(headAccess, HeadTextFrameH.class); 
    5049        } 
  • src/main/java/org/sophie2/main/func/text/model/HeadTextFrameH.java

     
    7272         * @return The {@link HotTextResourceH}. 
    7373         */ 
    7474        public HotTextResourceH getTextModel() { 
    75                 ResourceAccess textAccess =  
    76                                 getAccess().open(getMainResource(), getAccess().getAccessOptions()); 
     75                ResourceAccess textAccess = getAccess().open(getMainResource(), null); 
    7776 
    7877                return ResourceH.getHelper(textAccess, HotTextResourceH.class); 
    7978        } 
  • src/main/java/org/sophie2/base/model/resources/r4/access/MasterTopAccess.java

    #P org.sophie2.base.model.resources.r4
     
    66 
    77import org.sophie2.base.model.resources.r4.LocationPrefix; 
    88import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     9import org.sophie2.base.model.resources.r4.access.cacheKey.CacheKey; 
    910import org.sophie2.base.model.resources.r4.access.cacheKey.DelegatingAccessCacheKey; 
    1011import org.sophie2.base.model.resources.r4.changes.Change; 
    1112import org.sophie2.base.model.resources.r4.changes.ChangeEffect; 
     
    3233 */ 
    3334public abstract class MasterTopAccess extends BaseResourceAccess { 
    3435 
    35          
     36 
    3637        // Aspects used for tracking: 
    3738        private Map<Key<?>, Aspect> readAspects = new HashMap<Key<?>, Aspect>(); 
    3839        private Aspect headAspect = new Aspect(null); 
     
    4142         * The head revision of this <code>ResourceAccess</code>. 
    4243         */ 
    4344        protected ResourceRevision headRevision; 
    44          
     45 
    4546        /** 
    4647         * A ResourceRefR4 used as a user for master accesses. The master user  
    4748         * should not register changes since the {@link MasterTopAccess}es are not  
     
    4950         */ 
    5051        private static ResourceRefR4 masterUser = ResourceRefR4.make( 
    5152                        LocationPrefix.MEMORY + "master-user"); 
    52          
     53 
    5354        /** 
    5455         * The {@link AccessOptions} used by the  {@link MasterTopAccess}es.  
    5556         */ 
     
    6061         * They are memorized by their relative ref to the master and accessOptions.  
    6162         */ 
    6263        protected final Map<DelegatingAccessCacheKey, DelegatingAccess> delegatingAccessesCache =  
    63                                                         new HashMap<DelegatingAccessCacheKey, DelegatingAccess>(); 
    64          
     64                new HashMap<DelegatingAccessCacheKey, DelegatingAccess>(); 
     65 
    6566        /** 
    6667         * The root access that this master delegates operations for outer references. 
    6768         */ 
     
    8384                super(masterOptions, ref); 
    8485                this.rootAccess = parent; 
    8586                this.headRevision = (headRevision==null)? 
    86                                                                 LocalResourceRevision.getInitialRevision():headRevision; 
     87                                LocalResourceRevision.getInitialRevision():headRevision; 
    8788        } 
    88          
     89 
    8990        public ResourceAccess open(ResourceRefR4 ref, AccessOptions options) { 
    90                  
     91 
    9192                ResourceAccess res; 
    9293                assert (options != null):  
    9394                        "You can not use the master access options for delegating accesses"; 
     
    109110                                refToOpen = ResourceRefR4.getRelativeRef(getRef(),  
    110111                                                access.getRef().append(ref.getThisChildRef())); 
    111112                        } 
    112                          
    113                         DelegatingAccessCacheKey key = new DelegatingAccessCacheKey(refToOpen, options); 
     113 
     114                        DelegatingAccessCacheKey key =  
     115                                new DelegatingAccessCacheKey(this.location.append(refToOpen), options); 
    114116                        res = this.delegatingAccessesCache.get(key); 
    115117                        if (res == null) { 
    116118                                DelegatingAccess innerAccess = createInner(refToOpen, options); 
     
    126128 
    127129        //gets the resource access that does not point to a redirect 
    128130        private ResourceAccess getActualAccess(ResourceAccess access) { 
    129                  
     131 
    130132                if (RedirectR4.KIND.equals(ResourceR4.KEY_KIND.get(access))) { 
    131133                        ResourceRefR4 redirect = RedirectR4.KEY_TARGET.get(access); 
    132                          
     134 
    133135                        if (!redirect.equals(ResourceRefR4.NONE_REF)) { 
    134136                                ResourceAccess res = access.open(redirect, null); 
    135137                                return res; 
     
    139141        } 
    140142 
    141143        public void close() { 
     144                closeAccess(); 
    142145                // FIXME This should not be done this way. 
    143146                BaseLocator locator = (BaseLocator)this.rootAccess; 
    144                 locator.topAccessesCache.remove(locator.getCacheKey(getRef(), getAccessOptions())); 
     147                CacheKey key = locator.getCacheKey(getRef(), getAccessOptions()); 
     148                assert (locator.topAccessesCache.remove(key) != null) :  
     149                                "The master access should be in the accessesCache."; 
    145150        } 
    146          
     151 
    147152        public <T> T getRaw(Key<T> key) { 
    148153                if (!this.readAspects.containsKey(key)) { 
    149154                        this.readAspects.put(key, new Aspect(null)); 
     
    164169        } 
    165170 
    166171        public void registerChange(Change change) { 
     172                checkState(); 
    167173                registerChange(change, null); 
    168174        } 
    169175 
     
    219225                assert oldRevision.getId().equals(revision.getId()); 
    220226 
    221227        } 
     228 
    222229        public List<Change> syncFromSlave(RevisionId lastSync, 
    223230                        List<Change> slaveChanges) { 
    224231                throw new UnsupportedOperationException("This is not implemented yet."); 
    225232        } 
    226          
     233 
    227234        /** 
    228235         * Factory method for creation of delegating accesses. 
    229236         *  
     
    235242         *                      Inner access to the pointed sub resource.  
    236243         */ 
    237244        protected abstract DelegatingAccess createInner(ResourceRefR4 innerRef, 
    238                                                                                                 AccessOptions options); 
     245                        AccessOptions options); 
     246 
     247        public boolean isClosed() { 
     248                return this.closed; 
     249        } 
    239250} 
  • src/main/java/org/sophie2/base/model/resources/r4/access/DelegatingAccess.java

     
    1616 * their own revisions and model and simply delegate all operations to the  
    1717 * {@link MasterTopAccess} that created them. 
    1818 *  
    19  * @author meddle, mira 
     19 * @author mira 
    2020 */ 
    2121public abstract class DelegatingAccess extends BaseResourceAccess { 
    2222 
     
    2424         * The parent access that this inner delegates to. 
    2525         */ 
    2626        protected final MasterTopAccess masterAccess; 
    27          
     27 
    2828        /** 
    2929         * Default constructor with parameters. 
    3030         *  
     
    4040                super(options, location); 
    4141                this.masterAccess = parentAccess; 
    4242        } 
    43          
     43 
    4444        public ResourceAccess open(ResourceRefR4 ref, AccessOptions options) { 
    4545                AccessOptions optionsToSet = (options == null) ? getAccessOptions() : options; 
    4646                ResourceRefR4 toOpen = ref; 
     
    4848                        toOpen = this.location.append(ref); 
    4949                } 
    5050                SophieLog.trace("Reference to open : " + toOpen.getLocation()); 
    51                  
     51 
    5252                return this.masterAccess.open(toOpen, optionsToSet); 
    5353        } 
    5454 
    5555        public void close() { 
    56                 DelegatingAccessCacheKey key =  
    57                                                 new DelegatingAccessCacheKey(this.location, this.getAccessOptions()); 
    58                 this.masterAccess.delegatingAccessesCache.remove(key); 
    59                 if (this.masterAccess.delegatingAccessesCache.isEmpty()) { 
    60                         this.masterAccess.close(); 
     56                ResourceRefR4 ref = this.masterAccess.getRef().append(this.location); 
     57                DelegatingAccessCacheKey key = new DelegatingAccessCacheKey(ref, this.getAccessOptions()); 
     58                this.masterAccess.delegatingAccessesCache.get(key).closeAccess(); 
     59 
     60                for (DelegatingAccess access : this.masterAccess.delegatingAccessesCache.values()) { 
     61                        if (!access.isClosed()) { 
     62                                //There are unclosed delegating accesses 
     63                                return; 
     64                        } 
    6165                } 
     66                this.masterAccess.close(); 
     67        } 
     68         
     69        public boolean isClosed() { 
     70                if (this.closed) { 
     71                        return true; 
     72                } 
    6273 
     74                if (ResourceRefR4.CURRENT_REF.equals(this.location)) { 
     75                        return this.masterAccess.isClosed(); 
     76                } 
     77                BaseResourceAccess parent = (BaseResourceAccess) open(ResourceRefR4.PARENT_REF, null); 
     78                return parent.isClosed(); 
    6379        } 
    6480         
    6581        public List<Change> syncFromSlave(RevisionId lastSync, 
     
    6783                // TODO Auto-generated method stub 
    6884                return null; 
    6985        } 
    70          
     86 
    7187        public <T> T getRaw(Key<T> key) { 
    7288                // security 
    7389                return this.masterAccess.getRaw(ResourceR4.KEY_CHILDREN.sub(this.location).sub(key)); 
    7490        } 
    75          
     91 
    7692        public void registerChange(Change change) { 
    7793                // security 
     94                checkState(); 
    7895                this.masterAccess.registerChange(change); 
    7996        } 
    80          
     97 
    8198        public ResourceRevision getHead() { 
    8299                return this.masterAccess.getHead(); 
    83100        } 
    84          
     101 
    85102        @Override 
    86103        public final ResourceRefR4 getRef() { 
    87104                return this.masterAccess.getRef().sub(this.location); 
  • src/main/java/org/sophie2/base/model/resources/r4/access/ResourceAccess.java

     
    5858         */ 
    5959        public List<Change> syncFromSlave(RevisionId lastSync, 
    6060                        List<Change> slaveChanges); 
     61         
     62        /** 
     63         * Checks the state of the {@link ResourceAccess}. If the access if closed  
     64         * the resource it holds can not be modified in any way through this access. 
     65         *  
     66         * @return 
     67         *              true if the access if closed, false if it is open. 
     68         */ 
     69        public boolean isClosed(); 
    6170} 
  • src/main/java/org/sophie2/base/model/resources/r4/access/cacheKey/DelegatingAccessCacheKey.java

     
    7070                return true; 
    7171        } 
    7272         
     73        /** 
     74         * Checks is this key is a sub key of the given one. Sub key is key with the same  
     75         * {@link AccessOptions} and inner ref of the given one. 
     76         *  
     77         * @param key 
     78         *                      The parent key. 
     79         * @return 
     80         *                      True if the given key is parent to this one, false otherwise. 
     81         */ 
     82        public boolean isSubKey(DelegatingAccessCacheKey key) { 
     83                if (this.accessOptions.equals(key.accessOptions) 
     84                                && this.ref.getLocation().startsWith(key.ref.getLocation())) { 
     85                        return true; 
     86                } 
     87                return false; 
     88                 
     89        } 
    7390} 
  • src/main/java/org/sophie2/base/model/resources/r4/access/BaseResourceAccess.java

     
    1616 * @author meddle, mira 
    1717 */ 
    1818public abstract class BaseResourceAccess implements ResourceAccess { 
    19  
     19         
     20        /** 
     21         * Flag indicating if this access is closed.  
     22         */ 
     23        protected boolean closed; 
     24         
    2025        private final AccessOptions accessOptions; 
    2126        /** 
    2227         * The {@link ResourceRefR4} pointing to the resource kept by this access. 
     
    3540         *                      The {@link ResourceRefR4} for this access. 
    3641         */ 
    3742        public BaseResourceAccess(AccessOptions options, ResourceRefR4 location) { 
     43                this.closed = false; 
    3844                this.location = location; 
    3945                this.accessOptions = options;    
    4046        } 
     
    5561         * @return A {@link LocalResourceRevision} which is cloned by the current one. 
    5662         */ 
    5763        public ResourceRevision cloneHeadRevision() { 
     64                checkState(); 
    5865                ResourceRevision headRevision = getHead(); 
    5966                 
    6067                final ResourceModel copyModel; 
     
    7077                } 
    7178                return LocalResourceRevision.getInitialRevision(copyModel); 
    7279        } 
     80 
     81        /** 
     82         * Closes this access. 
     83         */ 
     84        public void closeAccess() { 
     85                this.closed = true; 
     86        } 
     87         
     88        /** 
     89         * Checks if this access is closed. This would mean that its resource is locked for changes. 
     90         */ 
     91        protected void checkState(){ 
     92                if (isClosed()) { 
     93                        throw new IllegalStateException("This access is already closed. You should " + 
     94                                                                                                "not change resource through it."); 
     95                } 
     96        }  
     97         
    7398} 
  • src/main/java/org/sophie2/base/model/resources/r4/access/BaseLocator.java

     
    77import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    88import org.sophie2.base.model.resources.r4.access.cacheKey.CacheKey; 
    99import org.sophie2.base.model.resources.r4.model.ResourceRevision; 
     10import org.sophie2.core.logging.SophieLog; 
    1011 
    1112/** 
    1213 * Base implementation of the {@link ResourceLocator} interface. 
     
    4445        public ResourceAccess create(ResourceRefR4 target,  
    4546                                                                AccessOptions options, ResourceRevision head) { 
    4647                CacheKey cacheKey = getCacheKey(target, options); 
    47                 assert (!this.topAccessesCache.containsKey(cacheKey)) :  
    48                         "This resource is already created - " + target; 
     48                if (this.topAccessesCache.containsKey(cacheKey)) { 
     49                        SophieLog.debug("The resource " + target + " is already created"); 
     50                        return null; 
     51                } 
    4952                MasterTopAccess masterAccess = createTop(target, options, head); 
    5053                this.topAccessesCache.put(cacheKey, masterAccess); 
    5154                return masterAccess.open(ResourceRefR4.CURRENT_REF, options); 
    5255        } 
    5356 
    5457        public void close() { 
    55                 throw new RuntimeException("You should not close the RootAccess!"); 
     58                for (MasterTopAccess topAccess : this.topAccessesCache.values()) { 
     59                        topAccess.close(); 
     60                } 
    5661        } 
    5762 
    5863        public AccessOptions getAccessOptions() { 
  • src/main/java/org/sophie2/dev/author/FakeAuthorMain.java

    #P org.sophie2.dev
     
    101101                //SophieLog.setMinLevel("org.sophie2.base.layout", LogLevel.DEBUG); 
    102102                //SophieLog.setMinLevel("org.sophie2.base.model.resources.r4", LogLevel.DEBUG); 
    103103                //SophieLog.setMinLevel("org.sophie2.base.model.resources.r4.access", LogLevel.INFO); 
    104                 SophieLog.setMinLevel("org.sophie2.main.media", LogLevel.ALL); 
    105                 SophieLog.setMinLevel("org.sophie2.main.media.natlib.output", LogLevel.NONE); 
     104                //SophieLog.setMinLevel("org.sophie2.main.media", LogLevel.ALL); 
     105                SophieLog.setMinLevel("", LogLevel.NONE); 
    106106                //SophieLog.setMinLevel("org.sophie2.main.func.timelines", LogLevel.DEBUG); 
    107107                //SophieLog.setMinLevel("org.sophie2.main.media.natlib.output.JavaSoundOutputBridge", LogLevel.TRACE); 
    108108                //SophieLog.setMinLevel("org.sophie2.main.media.natlib.input.JavaSoundInputBridge", LogLevel.TRACE);