Ticket #2278: deleteResources.2.patch

File deleteResources.2.patch, 67.8 KB (added by mira, 15 years ago)

The final version of the patch. There is no need to apply the other ones.

  • src/main/java/org/sophie2/server/webui/handlers/UnderConstructionHandler.java

    ### Eclipse Workspace Patch 1.0
    #P org.sophie2.server.webui
     
    1919 * @author pap 
    2020 */ 
    2121public class UnderConstructionHandler extends BaseHandlerSupport { 
    22          
     22 
     23        private static final long serialVersionUID = 1354668791633263387L; 
     24 
    2325        /** 
    2426         * The server location handled by this <code>UnderConstructionHandler</code> 
    2527         *  
  • src/main/java/org/sophie2/extra/func/scripting/model/persistence/RunScriptActionPersister.java

    #P org.sophie2.extra.func.scripting
     
    3535                ValueRef<ResourceRefR4> script = new ValueRef<ResourceRefR4>() { 
    3636                        @Override 
    3737                        public ResourceRefR4 getInitial() { 
    38                                 return ref.get().getRef(); 
     38                                return ref.get().getReferences().get(0); 
    3939                        } 
    4040                }; 
    4141 
  • src/main/java/org/sophie2/extra/func/scripting/logic/RunScriptLogic.java

     
    136136                         
    137137                        BookView bookView = event.getSource(BookView.class); 
    138138 
    139                         ResourceRefR4 scriptRef = action.getRef(); 
     139                        ResourceRefR4 scriptRef = action.getReferences().get(0); 
    140140                        ResourceAccess access = event.getEventParam( 
    141141                                        LinkEvent.RESOURCE_ACCESS_PARAM_INDEX, ResourceAccess.class); 
    142142                        ResourceAccess scriptAccess = access.open(scriptRef, null); 
  • src/main/java/org/sophie2/extra/func/scripting/links/RunScriptConfigurationPanel.java

     
    129129                                        && hud.holder().get() != null  
    130130                                        && hud.currentRule().get() != null 
    131131                                        && hud.currentRule().get().getAction() != null 
    132                                         && hud.currentRule().get().getAction() instanceof RunScriptAction 
    133                                         && ((RunScriptAction) hud.currentRule().get().getAction()).getRef() != null) { 
    134                                 ruleScript = ((RunScriptAction) hud.currentRule().get().getAction()).getRef(); 
     132                                        && hud.currentRule().get().getAction() instanceof RunScriptAction) { 
     133                                ResourceRefR4 ref = ((RunScriptAction) hud.currentRule().get().getAction()).getReferences().get(0); 
     134                                if (ref != null) { 
     135                                        ruleScript = ref;  
     136                                } 
    135137                        } 
    136138                        ScriptResourceH ruleScriptH = null; 
    137139                        BookH book = bdv.model().get(); 
  • src/main/java/org/sophie2/extra/func/scripting/links/RunScriptAction.java

     
    11package org.sophie2.extra.func.scripting.links; 
    22 
     3import java.util.ArrayList; 
     4import java.util.List; 
     5import java.util.Map; 
     6 
    37import org.sophie2.base.model.book.links.LinkAction; 
    48import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    5 import org.sophie2.base.model.resources.r4.immutables.ResourceRefWrapper; 
     9import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    610import org.sophie2.core.prolib.annot.Immutable; 
    711 
    812/** 
     
    1216 * @author deni, mitex 
    1317 */ 
    1418@Immutable(kind="run-script-action") 
    15 public class RunScriptAction extends LinkAction implements ResourceRefWrapper{ 
    16          
     19public class RunScriptAction extends LinkAction  
     20implements ResourceReferrer<RunScriptAction>{ 
     21 
    1722        private final ResourceRefR4 script; 
    18          
     23 
    1924        /** 
    2025         * Constructor. 
    2126         * @param script The script to execute 
     
    2934        public String getDescription() { 
    3035                return "Run script..."; 
    3136        } 
    32          
     37 
    3338        @Override 
    3439        public int hashCode() { 
    3540                return super.hashCode() + (31 * 
    36                                 (getRef() == null ? 0 : getRef().hashCode())); 
     41                                (this.script == null ? 0 : this.script.hashCode())); 
    3742        } 
    38          
     43 
    3944        @Override 
    4045        public boolean equals(Object obj) { 
    4146                if (!super.equals(obj)) { 
    4247                        return false; 
    4348                } 
    44                  
     49 
    4550                RunScriptAction action = (RunScriptAction) obj; 
    46                 if (action.getRef() != null) { 
    47                         return action.getRef().equals(getRef()); 
     51                if (action.script != null) { 
     52                        return action.script.equals(this.script); 
    4853                } 
    49                 return (action.getRef() == null) == (getRef() == null);  
     54                return (action.script == null) == (this.script == null);  
    5055        } 
    5156 
    52         public ResourceRefR4 getRef() { 
    53                 return this.script; 
     57        public RunScriptAction fixReferences( 
     58                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     59                return new RunScriptAction(replaces.get(this.script)); 
    5460        } 
    5561 
    56         public ResourceRefWrapper setRef(ResourceRefR4 newRef) { 
    57                 return new RunScriptAction(newRef); 
     62        public List<ResourceRefR4> getReferences() { 
     63                ArrayList<ResourceRefR4> res = new ArrayList<ResourceRefR4>(); 
     64                res.add(this.script); 
     65                return res; 
    5866        } 
    5967} 
  • src/main/java/org/sophie2/main/func/resources/logic/ResourceDeleteLogic.java

    #P org.sophie2.main.func.resources
     
    11package org.sophie2.main.func.resources.logic; 
    22 
    3 import java.util.ArrayList; 
    4 import java.util.List; 
    5  
    63import org.sophie2.base.dialogs.DialogManager; 
    74import org.sophie2.base.layout.model.ListPaletteItem; 
    8 import org.sophie2.base.model.book.ElementGroupH; 
     5import org.sophie2.base.model.book.BookH; 
    96import org.sophie2.base.model.book.ElementH; 
    10 import org.sophie2.base.model.book.FrameH; 
    11 import org.sophie2.base.model.book.PageH; 
    12 import org.sophie2.base.model.book.interfaces.ResourceFrame; 
    137import org.sophie2.base.model.book.resource.r4.BookR4; 
    148import org.sophie2.base.model.resources.r4.ResourceRefList; 
    159import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    1610import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    1711import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     12import org.sophie2.base.model.resources.r4.keys.Key; 
    1813import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    19 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
    2014import org.sophie2.core.mvc.EventFilterBuilder; 
    2115import org.sophie2.core.mvc.LogicR3; 
    2216import org.sophie2.core.mvc.OperationDef; 
     
    2418import org.sophie2.main.app.commons.book.BookDocView; 
    2519import org.sophie2.main.app.commons.book.BookView; 
    2620import org.sophie2.main.app.commons.element.ElementView; 
    27 import org.sophie2.main.app.commons.element.GroupView; 
    28 import org.sophie2.main.app.commons.frame.FrameView; 
    2921import org.sophie2.main.app.commons.page.RootPageView; 
    3022import org.sophie2.main.dialogs.input.ConfirmDialogInput; 
    3123import org.sophie2.main.dialogs.input.DialogUtils; 
     
    3628/** 
    3729 * Represents the logic for handling the deleting resources event. 
    3830 *  
    39  * @author diana 
     31 * @author diana, mira 
    4032 */ 
    4133public enum ResourceDeleteLogic implements OperationDef { 
    42          
     34 
    4335        /** 
    4436         * Handles the deleting of the existing resources in the book. 
    4537         */ 
     
    5446                public boolean handle(EventR3 event) { 
    5547                        DeleteResourceButton source = event.getSource(DeleteResourceButton.class); 
    5648                        ResourceDetailsPalette palette = source.findParentElement(ResourceDetailsPalette.class); 
    57                          
     49 
    5850                        assert palette != null : "The source must not be null!"; 
    5951 
    6052                        BookDocView bookDocView = palette.findNearestElement(null, BookDocView.class); 
     
    6254                                palette.resourcePalette().get().firstSelectedItem().get(); 
    6355 
    6456                        if (selectedItem == null) { 
    65                                 showUserMsg("First select a resource to delete it!"); 
     57                                DialogUtils.showErrorDialog(null, "Select resource to delete.", 
     58                                                                                                                "No resource selected."); 
    6659                                return true;                             
    6760                        } 
    6861 
    6962                        ConfirmDialogInput input = new ConfirmDialogInput(null, 
    7063                                        "Are you sure you want to delete this resource?", "Warning", false);                     
    7164                        ConfirmDialogInput.Response result = DialogManager.get().showDialog(input); 
    72                          
     65 
    7366                        if (result == ConfirmDialogInput.Response.NO  
    7467                                        || result == ConfirmDialogInput.Response.CLOSED) { 
    7568                                return true; 
    7669                        } 
    77                          
    7870                        ResourceH resource = ((ResourceItem) selectedItem).resource().get(); 
    79                         if (!(resource instanceof ElementH)) { 
    80                                 if (!isMainResourceUsed(resource, bookDocView)) { 
    81                                         return deleteMainResource(resource, bookDocView); 
    82                                 } 
    83                                  
    84                                 showUserMsg("The selected resource is currently in use."); 
    85                                 return true; 
     71                        if (resource instanceof ElementH) { 
     72                                return deleteElement(source, (ElementH)resource, bookDocView); 
     73                        }  
     74                        BookH book = bookDocView.model().get(); 
     75                        if (!ResourceH.isResourceUsed(resource, book, BookH.SUBELEMENTS_KEYS)) { 
     76                                return deleteResource(resource, book); 
    8677                        } 
    87                          
    88                         return deleteResource(source, (ElementH)resource, bookDocView); 
    89                 } 
    90                  
    91                 private boolean isMainResourceUsed(ResourceH resource, BookDocView bookDocView) { 
    92                         List<FrameView> allFrameViews = getAllFrameViews(bookDocView); 
    93                         ResourceRefR4 resourceRef = resource.getAccess().getRef(); 
    94                          
    95                         for (FrameView frameView : allFrameViews) { 
    96                                 String resName =  
    97                                         ResourceFrame.KEY_MAIN_RESOURCE.get(frameView.getAccess()).getName(); 
    98                                  
    99                                 if (resName.equals(resourceRef.getName())) { 
    100                                         return true; 
    101                                 } 
    102                         } 
    103                          
    104                         return false; 
    105                 } 
    106                  
    107                 private List<FrameView> getAllFrameViews(BookDocView bookDocView) { 
    108                         List<FrameView> availableViews = new ArrayList<FrameView>(); 
    109                         BookView bookView = bookDocView.bookView().get(); 
    110                          
    111                         for (ResourceRefR4 pageRef : bookView.model().get().getPages()) { 
    112                                 RootPageView rootPageView = bookView.getPageView(pageRef); 
    113                                 List<FrameView> pageFrameView = rootPageView.getAll(FrameView.class); 
    114                                 availableViews.addAll(pageFrameView); 
    115                         } 
    116                          
    117                         return availableViews; 
    118                 } 
    119                  
    120                 private void showUserMsg(String text) { 
    121                         DialogUtils.showErrorDialog(null,text, "Cannot delete it."); 
    122                 } 
    123                  
    124                 private boolean deleteMainResource(ResourceH resource, BookDocView bookDocView) { 
    125                         ResourceAccess bookAccess = bookDocView.bookView().get().getAccess(); 
    126                         if (resource.getRef().equals(bookAccess.getRef())) {//the resource is the book 
    127                                 showUserMsg("The resource to delete should not be book resource."); 
    128                                 return true; 
    129                         } 
    130                          
    131                         final ResourceRefR4 resourceRef = resource.getRef().getThisChildRef(); 
    132                         new AutoAction("Remove Main Resource", true) { 
    133                                 @Override 
    134                                 public void performAuto() { 
    135                                         getChanger().removeResource(resourceRef); 
    136                                 } 
    13778 
    138                         }.register(bookAccess); 
    139                          
     79                                DialogUtils.showErrorDialog(null, "The selected resource is currently in use.", 
     80                                  "Could not delete resource"); 
    14081                        return true; 
    14182                } 
    142                  
    143                 private boolean deleteResource(DeleteResourceButton source, ElementH resource, BookDocView bookDocView) { 
    144                         ElementView view = null; 
    145                          
    146                         if (resource instanceof PageH) { 
    147                                 //if the resource is a page template 
    148                                 final ResourceRefR4 pageRef = resource.getRef().getThisChildRef(); 
    149                                 ResourceRefList pageTemplates = BookR4.KEY_PAGE_TEMPLATES.get(bookDocView.getAccess()); 
    150                                 int pageTemplateNumber = containing(pageTemplates,pageRef); 
    151                                  
    152                                 if (pageTemplateNumber != -1) { 
    153                                         boolean isUsedPageTemplate = isUsedPageTemplate(resource.getRef().getThisChildRef(), bookDocView); 
    154                                          
    155                                         if (isUsedPageTemplate) { 
    156                                                 showUserMsg("The page template is currently in use."); 
    157                                                 return true; 
    158                                         } 
    159                                          
    160                                         final ResourceRefList finalPageTemplateList = pageTemplates.remove(pageTemplateNumber); 
    161                                         new AutoAction("Set New Page Template List", false) { 
    162                                                 @Override 
    163                                                 public void performAuto() { 
    164                                                         getChanger().removeResource(pageRef); 
    165                                                         getChanger().setRaw(BookR4.KEY_PAGE_TEMPLATES, finalPageTemplateList); 
    166                                                 } 
    167  
    168                                         }.register(bookDocView.getAccess()); 
    169                                         return true; 
    170                                          
    171                                 } 
    172                                 view = bookDocView.bookView().get().getPageView(resource.getRef().getThisChildRef()); 
    173                                  
    174                         } else if(resource instanceof FrameH) { 
    175                                 //if frame template 
    176                                 final ResourceRefR4 frameRef = resource.getRef().getThisChildRef(); 
    177                                 ResourceRefList frameTemplates = BookR4.KEY_FRAME_TEMPLATES.get(bookDocView.getAccess()); 
    178                                 int frameTemplateNumber = containing(frameTemplates, frameRef); 
    179                                  
    180                                 boolean isUsed = isUsedFrameTemplate(frameRef, bookDocView); 
    181                                 if (isUsed) { 
    182                                         showUserMsg("The frame template is currently in use."); 
    183                                         return true; 
    184                                 } 
    185                                  
    186                                 if (frameTemplateNumber != -1 && ! isUsed) { 
    187                                         final ResourceRefList finalFrameTemplateList =  
    188                                                 frameTemplates.remove(frameTemplateNumber); 
    189                                         new AutoAction("Set New Frame Template List", false) { 
    190                                                 @Override 
    191                                                 public void performAuto() { 
    192                                                         getChanger().removeResource(frameRef); 
    193                                                         getChanger().setRaw(BookR4.KEY_FRAME_TEMPLATES, finalFrameTemplateList); 
    194                                                 } 
    195  
    196                                         }.register(bookDocView.getAccess()); 
    197                                         return true; 
    198                                 } 
    199                                 view = findView(frameRef,bookDocView.bookView().get(), FrameView.class); 
    200  
    201                         } else if (resource instanceof ElementGroupH) { 
    202                                 //if group 
    203                                 ResourceRefR4 grRef = resource.getRef().getThisChildRef(); 
    204                                 view = findView(grRef, bookDocView.bookView().get(), GroupView.class); 
    205                         } 
    206                          
    207                         if (view != null) { 
    208                                 LogicR3.fire(source,bookDocView,null,null,BookView.EventIds.ELEMENT_DELETED, view); 
    209                         } 
    210                          
     83        }; 
     84         
     85        //TODO Think of a better place for those: 
     86         
     87        /** 
     88         * Deletes a resource.  
     89         *  
     90         * @param resource 
     91         *                      The resource to delete. 
     92         * @param book 
     93         *                      The parent of the resource.   
     94         *                       
     95         * @return 
     96         *                      true if the resource was found and deleted,  
     97         *                      false if there was a problem. 
     98         */ 
     99        static boolean deleteResource(ResourceH resource, BookH book) { 
     100                ResourceAccess bookAccess = book.getAccess(); 
     101                if (resource.getRef().equals(bookAccess.getRef())) {//the resource is the book 
     102                        DialogUtils.showErrorDialog(null, "You can not delete the book.",  
     103                                                                                                "Can not delete resource."); 
    211104                        return true; 
    212105                } 
    213106 
    214                 private int containing(ResourceRefList list, ResourceRefR4 ref) { 
    215                         for (int i = 0; i < list.size(); ++i) { 
    216                                 if (list.get(i).getThisChildRef().equals(ref)) { 
    217                                         return i; 
    218                                 } 
     107                final ResourceRefR4 resourceRef = ResourceRefR4.getRelativeRef( 
     108                                bookAccess.getRef(), resource.getRef()); 
     109                new AutoAction("Remove resource", true) { 
     110                        @Override 
     111                        public void performAuto() { 
     112                                getChanger().removeResource(resourceRef); 
    219113                        } 
    220                          
    221                         return -1; 
    222                 } 
     114 
     115                }.register(bookAccess); 
     116 
     117                return true; 
     118        } 
     119 
     120        /** 
     121         *  Helper method used when deleting an element resource. Those are  
     122         *  pages, frames, groups, etc. Sometimes special logic is needed   
     123         *      and this method fires events to be handled. 
     124         *  
     125         * @param source 
     126         *                      The source of event to be fired. 
     127         * @param resource 
     128         *                      The resource we need to remove. 
     129         * @param bookDocView 
     130         *                      The bookDocView whose element we want to delete. 
     131         * @return 
     132         *                      true if the element was found and deleted,  
     133         *                      false if there was a problem.    
     134         */ 
     135        static boolean deleteElement(DeleteResourceButton source, ElementH resource, BookDocView bookDocView) { 
     136                BookView bookview = bookDocView.bookView().get(); 
     137                ResourceRefR4 bookRef = bookview.getAccess().getRef();  
     138                ResourceRefR4 elementRef = ResourceRefR4.getRelativeRef(bookRef, resource.getRef()); 
     139                BookH book = bookview.model().get(); 
     140                ElementView elementView = null; 
    223141                 
    224                 private boolean isUsedPageTemplate(ResourceRefR4 pageTemplate, BookDocView bookDocView) { 
    225                         BookView bookView = bookDocView.bookView().get(); 
    226                          
    227                         for (ResourceRefR4 page : bookView.model().get().getPages()) { 
    228                                 RootPageView pageView = bookView.getPageView(page); 
    229                                 ResourceRefR4 currentTemplate = ResourceRefR4.NONE_REF; 
    230                                  
    231                                 if (!ResourceR4.KEY_TEMPLATE.get(pageView.getAccess()).equals(currentTemplate)) { 
    232                                         currentTemplate =  ResourceR4.KEY_TEMPLATE.get(pageView.getAccess()). 
    233                                         getThisChildRef(); 
    234                                 } 
    235                                  
    236                                 if (currentTemplate.equals(pageTemplate)) { 
    237                                         return true; 
    238                                 } 
     142                if (book.getPages().contains(elementRef)) { 
     143                        elementView = bookDocView.bookView().get().getPageView(elementRef); 
     144                } else { 
     145                        elementView = findElementView(elementRef, bookview); 
     146                } 
     147                if (elementView != null) { 
     148                        return LogicR3.fire(source, bookDocView, null, null, BookView.EventIds.ELEMENT_DELETED, 
     149                                        elementView); 
     150                } 
    239151 
    240                         } 
    241                         return false; 
     152                if (!ResourceH.isResourceUsed(resource, book, BookH.SUBELEMENTS_KEYS)  
     153                                && (removeTemplateElement(BookR4.KEY_PAGE_TEMPLATES, elementRef, bookview) || 
     154                                        removeTemplateElement(BookR4.KEY_FRAME_TEMPLATES, elementRef, bookview))) { 
     155                        return true; 
    242156                } 
    243157                 
    244                 private boolean isUsedFrameTemplate(ResourceRefR4 frameTemplate, BookDocView bookDocView) { 
    245                         BookView bookView = bookDocView.bookView().get(); 
    246                         for (ResourceRefR4 page : bookView.model().get().getPages()) { 
    247                                 RootPageView pageView = bookView.getPageView(page); 
    248                                 List<FrameView> frames = pageView.getAll(FrameView.class); 
    249                                  
    250                                 for (FrameView frame : frames) { 
    251                                         ResourceRefR4 currentTemplate = ResourceRefR4.NONE_REF; 
    252                                         if (!ResourceR4.KEY_TEMPLATE.get(frame.getAccess()).equals(currentTemplate)) { 
    253                                                 currentTemplate =  ResourceR4.KEY_TEMPLATE.get(frame.getAccess()). 
    254                                                 getThisChildRef(); 
    255                                         } 
    256                                         if (currentTemplate.equals(frameTemplate)) { 
    257                                                 return true; 
    258                                         } 
    259                                 } 
     158                DialogUtils.showErrorDialog(null,       "The selected resource is currently in use.", 
     159                                                                                        "Could not delete resource"); 
     160                return false; 
     161        } 
    260162 
     163        private static ElementView findElementView(ResourceRefR4 ref, BookView bookView) { 
     164                ResourceRefR4 bookRef = bookView.getAccess().getRef();  
     165                for (ResourceRefR4 pageRef : bookView.model().get().getPages()) { 
     166                        RootPageView pageView = bookView.getPageView(pageRef); 
     167                        for (ElementView elementView : pageView.getAll(ElementView.class)) { 
     168                                ResourceRefR4 elementRef = ResourceRefR4.getRelativeRef(bookRef, 
     169                                                                                                elementView.getAccess().getRef()); 
     170                                if (elementRef.equals(ref)) { 
     171                                        return elementView; 
     172                                } 
    261173                        } 
    262                         return false; 
    263174                } 
    264                  
    265                 private ElementView findView(ResourceRefR4 groupRef, BookView bookView, 
    266                                 Class<? extends ElementView> searchedClass) { 
    267                         for (ResourceRefR4 pageRef : bookView.model().get().getPages()) { 
    268                                 RootPageView pageView = bookView.getPageView(pageRef); 
    269                                 for (ElementView elementView : pageView.getAll(searchedClass)) { 
    270                                         if (elementView.getAccess().getRef().getThisChildRef().equals(groupRef)) { 
    271                                                 return elementView; 
    272                                         } 
     175                return null; 
     176        } 
     177         
     178        private static boolean removeTemplateElement(final Key<ResourceRefList> key,  
     179                                                                                        final ResourceRefR4 ref, BookView bookView) { 
     180                ResourceAccess bookAccess = bookView.getAccess(); 
     181                final ResourceRefList templates = key.get(bookAccess); 
     182                if (templates.contains(ref)) { 
     183                        new AutoAction("Remove template.", true) { 
     184                                @Override 
     185                                public void performAuto() { 
     186                                        getChanger().removeResource(ref); 
     187                                        getChanger().setRaw(key, templates.remove(ref)); 
    273188                                } 
    274                         } 
     189 
     190                        }.register(bookAccess); 
    275191                         
    276                         return null; 
     192                        return true; 
    277193                } 
     194                return false; 
    278195        } 
    279  
    280196} 
     197 
     198 
  • src/main/java/org/sophie2/main/app/commons/util/DeletePageUtil.java

    #P org.sophie2.main.app.commons
     
    11package org.sophie2.main.app.commons.util; 
    22 
    33import org.sophie2.base.model.book.BookH; 
     4import org.sophie2.base.model.book.PageH; 
    45import org.sophie2.base.model.resources.r4.ResourceRefList; 
    56import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    67import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     8import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    79import org.sophie2.main.app.commons.book.BookView; 
    810import org.sophie2.main.app.commons.page.RootPageView; 
     11import org.sophie2.main.dialogs.input.DialogUtils; 
    912 
    1013/** 
    1114 * Util class used for helper methods for deleting a page. 
     
    2629         *                      True if the page was removed successfully.  
    2730         */ 
    2831        public static boolean deletePage(RootPageView pageViewToDel, boolean isSign) { 
     32                PageH page = pageViewToDel.model().get(); 
    2933                BookView bookView = pageViewToDel.parent().get(); 
    3034                BookH book = bookView.model().get(); 
    31  
     35                 
     36                if (ResourceH.isResourceUsed(page, book, BookH.SUBELEMENTS_KEYS)) { 
     37                        DialogUtils.showErrorDialog(null, "The selected page is used by other resources.", 
     38                          "Could not delete page"); 
     39                        return true; 
     40                } 
     41                 
    3242                final ResourceRefR4 pageRef = ResourceRefR4.getRelativeRef( 
    33                                 book.getAccess().getRef(), pageViewToDel.model().get().getRef());  
     43                                book.getAccess().getRef(), page.getRef());  
    3444                final ResourceRefList pages = book.getPages(); 
    3545 
    3646                // TODO This check should be in the view, not in the logic. 
  • src/main/java/org/sophie2/main/app/commons/book/BookView.java

     
    395395                        refToOpen = pages.get(0); 
    396396                } 
    397397 
    398                 ResourceAccess pageAccess = access().get().open(refToOpen, 
    399                                 access().get().getAccessOptions()); 
     398                ResourceAccess pageAccess = access().get().open(refToOpen, null); 
    400399                RootPageView res = AppViewUtil.getView(this, pageAccess, RootPageView.class); 
    401400                if (!openPageViews().get().contains(res)) { 
    402401                        openPageViews().add(res); 
  • src/main/java/org/sophie2/base/model/resources/r4/resources/ResourceH.java

    #P org.sophie2.base.model.resources.r4
     
    1717import org.sophie2.base.model.resources.r4.keys.ChildrenKey; 
    1818import org.sophie2.base.model.resources.r4.keys.Key; 
    1919import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 
     20import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    2021import org.sophie2.core.prolib.errors.NotAvailableException; 
    2122import org.sophie2.core.prolib.impl.BaseProObject; 
    2223import org.sophie2.core.prolib.interfaces.Prop; 
     
    462463                return children; 
    463464        } 
    464465         
     466        /** 
     467         * Helper method used to determine whether a resource is referred to 
     468         * from other resource. It looks through all keys of the parent and  
     469         * its sub resources. Resource is not considered to refer itself.  
     470         *  
     471         * @param resource 
     472         *                      The resource we are looking for. 
     473         * @param parent 
     474         *                      The resource in which to look for refs. 
     475         * @param exclusions 
     476         *                      The keys we want to exclude from the search. Most often those 
     477         *                       are the pages, templates and sub-elements keys. 
     478         * @return 
     479         *                      true if the resource is referred to by the parent resource. 
     480         */ 
     481        public static boolean isResourceUsed(ResourceH resource, ResourceH parent,  
     482                                                                                                List<Key<ResourceRefList>> exclusions) { 
     483                if (resource.equals(parent)) { 
     484                        return false; 
     485                } 
     486                ResourceRefR4 resourceRef = resource.getRef(); 
     487                Class<ResourceR4> clazz = ResourceR4.getClassByKind(parent.getKind()); 
     488                Map<String, Key<?>> keys = ResourceR4.getKnownKeys(clazz); 
     489                for (Key<?> key : keys.values()) { 
     490                        if (!exclusions.contains(key) && 
     491                                        contains(key.getValueClass().getInterfaces(), ResourceReferrer.class)) { 
     492                                ResourceReferrer<?> referrer =  
     493                                        (ResourceReferrer<?>) key.get(parent.getAccess()); 
     494                                List<ResourceRefR4> pointedRefs = referrer.getReferences(); 
     495                                for (ResourceRefR4 ref : pointedRefs) { 
     496                                        if (ref.isRelative()) { 
     497                                                ref = parent.getRef().append(ref); 
     498                                        } 
     499                                        if (resourceRef.equals(ref)) { 
     500                                                return true; 
     501                                        } 
     502                                } 
     503                        } 
     504                } 
     505                ResourceRefList children = parent.getChildren(); 
     506                if (children != null) { 
     507                        for (ResourceRefR4 childRef : children) { 
     508                                ResourceAccess childAccess = parent.getAccess().open(childRef, null); 
     509                                ResourceH child = ResourceH.getHelper(childAccess); 
     510                                if (isResourceUsed(resource, child, exclusions)) { 
     511                                        return true; 
     512                                } 
     513                        } 
     514                } 
     515                return false; 
     516        } 
     517 
     518        private static boolean contains(Class<?>[] interfaces, Class<?> lookFor) { 
     519                for (Class<?> clazz : interfaces) { 
     520                        if (clazz.equals(lookFor)) { 
     521                                return true; 
     522                        } 
     523                } 
     524                return false; 
     525        } 
     526         
    465527} 
     528 No newline at end of file 
  • src/main/java/org/sophie2/base/model/resources/r4/changes/ModelResourceChanger.java

     
    22 
    33import java.util.ArrayList; 
    44import java.util.Collection; 
     5import java.util.HashMap; 
    56import java.util.List; 
     7import java.util.Map; 
    68 
    79import org.sophie2.base.commons.util.ImmList; 
    8 import org.sophie2.base.model.resources.r4.ResourceRefList; 
    910import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    1011import org.sophie2.base.model.resources.r4.immutables.NaiveSubEntryNames; 
    11 import org.sophie2.base.model.resources.r4.immutables.ResourceRefHolder; 
    1212import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 
    1313import org.sophie2.base.model.resources.r4.keys.ChildrenKey; 
    1414import org.sophie2.base.model.resources.r4.keys.Key; 
    1515import org.sophie2.base.model.resources.r4.keys.RootKey; 
    1616import org.sophie2.base.model.resources.r4.keys.UndefinedKey; 
    1717import org.sophie2.base.model.resources.r4.model.ResourceModel; 
     18import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    1819import org.sophie2.base.model.resources.r4.resources.RedirectR4; 
    1920import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
    2021 
     
    168169                        return; 
    169170                } 
    170171                 
    171                 if (current instanceof ResourceRefR4) { 
    172                         current = (T) rewriteRef(source, destination,(ResourceRefR4) current); 
    173                 } 
    174                  
    175                 if (current instanceof ResourceRefHolder) { 
    176                         ResourceRefHolder holder = (ResourceRefHolder) current; 
    177                         ResourceRefList rewritenRefs = ResourceRefList.EMPTY; 
    178                         ResourceRefList list = holder.getRefs(); 
    179                         for (ResourceRefR4 oldRef : list) { 
     172                if (current instanceof ResourceReferrer<?>) { 
     173                        ResourceReferrer<?> referer = (ResourceReferrer<?>) current; 
     174                        List<ResourceRefR4> oldRefs = referer.getReferences(); 
     175                        Map<ResourceRefR4, ResourceRefR4> replaces =  
     176                                new HashMap<ResourceRefR4, ResourceRefR4>(); 
     177                        for (ResourceRefR4 oldRef : oldRefs) { 
    180178                                ResourceRefR4 correctRef = rewriteRef(source, destination, oldRef); 
    181                                 rewritenRefs = rewritenRefs.add(correctRef); 
     179                                if (!oldRef.equals(correctRef)) { 
     180                                        replaces.put(oldRef, correctRef); 
     181                                } 
    182182                        } 
    183                         current = (T) holder.rewriteRefs(rewritenRefs); 
     183                        current = (T) referer.fixReferences(replaces); 
    184184                } 
    185185                 
    186186                setRaw(destKey, current); 
  • src/main/java/org/sophie2/base/model/resources/r4/immutables/ResourceRefWrapper.java

     
    1 package org.sophie2.base.model.resources.r4.immutables; 
    2  
    3 import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    4 import org.sophie2.core.prolib.annot.Immutable; 
    5  
    6 /** 
    7  * Interface used by to manipulate resource refs that are wrapped. 
    8  *  
    9  * @author mira 
    10  */ 
    11 @Immutable 
    12 public interface ResourceRefWrapper { 
    13          
    14         /** 
    15          * Gets the ref of this <code>ResourceRefWrapper</code>. 
    16          *  
    17          * @return 
    18          *                      ResourceRefR4 wrapped by this immutable.  
    19          */ 
    20         public ResourceRefR4 getRef(); 
    21          
    22         /** 
    23          * Method used for producing <code>ResourceRefWrapper</code>s identical  
    24          * to this one but with different <code>ResourceRefR4</code>. 
    25          *  
    26          * @param newRef 
    27          *                      The ref to be set to the new wrapper.  
    28          *  
    29          * @return 
    30          *                      New <code>ResourceRefWrapper</code> that is copy of this one 
    31          *                      but with different ref. 
    32          */ 
    33         public ResourceRefWrapper setRef(ResourceRefR4 newRef); 
    34  
    35 } 
  • src/main/java/org/sophie2/base/model/resources/r4/ResourceRefList.java

     
    9595        } 
    9696         
    9797        @Override 
     98        public ResourceRefList remove(ResourceRefR4 ref) { 
     99                return (ResourceRefList) super.remove(ref); 
     100        } 
     101         
     102        @Override 
    98103        protected ResourceRefList produce(List<ResourceRefR4> newData) { 
    99104                return new ResourceRefList(newData); 
    100105        } 
  • src/main/java/org/sophie2/main/app/halos/frame/FrameHalosLogic.java

    #P org.sophie2.main.app.halos
     
    33import org.sophie2.base.commons.util.ImmList; 
    44import org.sophie2.base.dialogs.DialogManager; 
    55import org.sophie2.base.halos.HaloButton; 
     6import org.sophie2.base.model.book.BookH; 
    67import org.sophie2.base.model.book.ElementH; 
    78import org.sophie2.base.model.book.FrameH; 
    89import org.sophie2.base.model.book.interfaces.CompositeElement; 
     
    1213import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    1314import org.sophie2.base.model.resources.r4.changes.AutoAction; 
    1415import org.sophie2.base.model.resources.r4.keys.TemplatedKey.Mode; 
     16import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    1517import org.sophie2.base.visual.VisualElement; 
    1618import org.sophie2.core.mvc.EventFilterBuilder; 
    1719import org.sophie2.core.mvc.LogicR3; 
     
    2527import org.sophie2.main.app.commons.util.AppViewUtil; 
    2628import org.sophie2.main.app.halos.common.AppHaloUtil; 
    2729import org.sophie2.main.dialogs.input.ConfirmDialogInput; 
     30import org.sophie2.main.dialogs.input.DialogUtils; 
    2831 
    2932/** 
    3033 * Handles events fired by the frame halos. 
     
    121124                                        "Are you sure you want to delete this frame?", "Warning", false);                        
    122125                        ConfirmDialogInput.Response result = DialogManager.get().showDialog(cdi); 
    123126 
    124                         FrameRemoveHaloButton halo =  
    125                                 event.getSource(FrameRemoveHaloButton.class); 
     127                        FrameRemoveHaloButton halo = event.getSource(FrameRemoveHaloButton.class); 
     128                         
    126129                        if (!(result == ConfirmDialogInput.Response.NO  
    127130                                        || result == ConfirmDialogInput.Response.CLOSED)) { 
    128131                                FrameView frameView = AppHaloUtil.getSingleFrameView(halo); 
     
    151154                public boolean handle(EventR3 event) { 
    152155                        FrameView frameView = event.getEventParam(BookView.EventIds.VIEW_PARAM_INDEX, 
    153156                                        FrameView.class); 
     157                        BookH bookH = event.getContext(BookDocView.class).bookView().get().model().get(); 
    154158                        FrameH frame = frameView.model().get();  
    155159 
     160                        if (ResourceH.isResourceUsed(frame, bookH, BookH.SUBELEMENTS_KEYS)) { 
     161                                DialogUtils.showErrorDialog(null, "The selected frame is used by other resources.", 
     162                                  "Could not delete frame"); 
     163                                return true; 
     164                        } 
     165                         
    156166                        ElementView parentView = frameView.parent().get(); 
    157167                        ElementH parent = parentView.model().get(); 
    158168                        ResourceRefR4 frameRef = frame.getRef(); 
  • src/main/java/org/sophie2/main/app/halos/grouping/GroupHalosLogic.java

     
    55 
    66import org.sophie2.base.commons.util.ImmList; 
    77import org.sophie2.base.halos.HaloButton; 
     8import org.sophie2.base.model.book.BookH; 
    89import org.sophie2.base.model.book.ElementGroupH; 
    910import org.sophie2.base.model.book.ElementH; 
    1011import org.sophie2.base.model.book.FrameH; 
     
    1617import org.sophie2.base.model.resources.r4.ResourceUtil; 
    1718import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    1819import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     20import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    1921import org.sophie2.core.mvc.EventFilterBuilder; 
    2022import org.sophie2.core.mvc.OperationDef; 
    2123import org.sophie2.core.mvc.SortKey; 
     
    2931import org.sophie2.main.app.commons.page.PageWorkArea; 
    3032import org.sophie2.main.app.commons.page.PwaSelector; 
    3133import org.sophie2.main.app.halos.common.AppHaloUtil; 
     34import org.sophie2.main.dialogs.input.DialogUtils; 
    3235 
    3336/** 
    3437 * Controller for grouping operations. 
     
    209212                        filter.setEventId(BookView.EventIds.ELEMENT_DELETED); 
    210213                        filter.setContextClass(BookDocView.class); 
    211214                        filter.setEventParamClass(BookView.EventIds.VIEW_PARAM_INDEX, GroupView.class); 
    212                          
    213215                } 
    214216 
    215217                public boolean handle(EventR3 event) { 
     218                         
    216219                        GroupView groupView = event.getEventParam(BookView.EventIds.VIEW_PARAM_INDEX, 
    217220                                        GroupView.class); 
    218                         final ResourceRefR4 grRef = groupView.getAccess().getRef().getThisChildRef(); 
    219                         ResourceAccess parentAccess = ((ElementView) groupView.parent().get()).getAccess(); 
    220                         final ImmList<ActivationChannel> channels =  
     221                        BookH book = event.getContext(BookDocView.class).bookView().get().model().get(); 
     222                        ElementGroupH group = groupView.model().get(); 
     223                        if (ResourceH.isResourceUsed(group, book, BookH.SUBELEMENTS_KEYS)) { 
     224                                DialogUtils.showErrorDialog(null, "The selected group is used by other resources.", 
     225                                  "Could not delete group"); 
     226                                return true; 
     227                        } 
     228                         
     229                        ResourceRefR4 groupRef = group.getAccess().getRef(); 
     230                        ElementH parentH = ((ElementView) groupView.parent().get()).model().get(); 
     231                         
     232                        final ResourceRefR4 relativeGroupRef =  
     233                                ResourceRefR4.getRelativeRef(groupRef, parentH.getRef()); 
     234                        ResourceAccess parentAccess = parentH.getAccess(); 
     235                        ImmList<ActivationChannel> channels =  
    221236                                CompositeElement.KEY_SUB_ELEMENTS.get(parentAccess); 
    222                         final ActivationChannel frameChan =  
    223                                 ((ElementView) groupView.parent().get()).model().get().getActivationChannel(grRef); 
     237                        ActivationChannel frameChan = parentH.getActivationChannel(relativeGroupRef); 
    224238                         
     239                        final ImmList<ActivationChannel> newChannels = channels.remove(frameChan); 
    225240                        new AutoAction("Delete Group.", true) { 
    226241                                @Override 
    227242                                public void performAuto() { 
    228                                         getChanger().removeResource(grRef); 
    229                                         getChanger().setRaw( 
    230                                                         CompositeElement.KEY_SUB_ELEMENTS, channels.remove(frameChan)); 
     243                                        getChanger().removeResource(relativeGroupRef); 
     244                                        getChanger().setRaw(CompositeElement.KEY_SUB_ELEMENTS, newChannels); 
    231245                                } 
    232246                        }.register(parentAccess); 
    233247                         
  • src/main/java/org/sophie2/main/func/links/persist/GoToPageActionPersister.java

    #P org.sophie2.main.func.links
     
    3535                ValueRef<ResourceRefR4> page = new ValueRef<ResourceRefR4>() { 
    3636                        @Override 
    3737                        public ResourceRefR4 getInitial() { 
    38                                 return source.get().getRef(); 
     38                                return source.get().getReferences().get(0); 
    3939                        } 
    4040                }; 
    4141                 
  • src/main/java/org/sophie2/main/func/links/ConfigurationPanelsLogic.java

     
    11package org.sophie2.main.func.links; 
    22 
     3import java.util.HashMap; 
     4import java.util.Map; 
     5 
    36import org.sophie2.base.bound.ComboInput; 
    47import org.sophie2.base.bound.BoundControl.EventIds; 
    58import org.sophie2.base.model.book.FrameH; 
     
    9295                                                ResourceRefR4.getRelativeRef(holder.getRef(), targetFrame.getRef()); 
    9396                                         
    9497                                        assert currentRule.getAction() instanceof FrameShowingAction; 
    95                                          
    96                                         FrameShowingAction newAction = ( 
    97                                                         (FrameShowingAction)currentRule.getAction()).setRef(newRef); 
     98                                        FrameShowingAction action = (FrameShowingAction)currentRule.getAction(); 
     99                                        Map<ResourceRefR4, ResourceRefR4> replaces = new HashMap<ResourceRefR4, ResourceRefR4>(); 
     100                                        replaces.put(action.getReferences().get(0), newRef); 
     101                                        FrameShowingAction newAction = action.fixReferences(replaces ); 
    98102                                         
    99103                                        LinksUtil.addAction(hud, newAction); 
    100104                                } 
  • src/main/java/org/sophie2/main/func/links/actions/navigation/NavigationActionsLogic.java

     
    9393                        GoToPageAction action = event.getEventParam( 
    9494                                        LinkEvent.ACTION_PARAM_INDEX, GoToPageAction.class); 
    9595                         
    96                         if (action == null || action.getRef() == null) { 
     96                        if (action == null || action.getReferences().get(0) == null) { 
    9797                                return false; 
    9898                        } 
    9999                         
    100100                        ResourceAccess access = event.getEventParam( 
    101101                                        LinkEvent.RESOURCE_ACCESS_PARAM_INDEX, ResourceAccess.class); 
    102102                         
    103                         ResourceRefR4 pageRef = access.getRef().append(action.getRef()); 
     103                        ResourceRefR4 pageRef = access.getRef().append(action.getReferences().get(0)); 
    104104                        ResourceRefR4 relToBookPageRef =  
    105105                                ResourceRefR4.getRelativeRef(bv.getAccess().getRef(), pageRef); 
    106106                        if (bv.model().get().getIndexOf(relToBookPageRef) < 0) { 
  • src/main/java/org/sophie2/main/func/links/actions/showing/FrameShowingAction.java

     
    11package org.sophie2.main.func.links.actions.showing; 
    22 
     3import java.util.ArrayList; 
     4import java.util.List; 
     5 
    36import org.sophie2.base.model.book.links.LinkAction; 
    47import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    5 import org.sophie2.base.model.resources.r4.immutables.ResourceRefWrapper; 
     8import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    69 
    710/** 
    811 * Base class for {@link ShowFrameAction}, {@link HideFrameAction} and 
     
    1013 *  
    1114 * @author kyli 
    1215 */ 
    13 public abstract class FrameShowingAction extends LinkAction implements ResourceRefWrapper{ 
     16public abstract class FrameShowingAction extends LinkAction implements ResourceReferrer<FrameShowingAction>{ 
    1417         
    15         private final ResourceRefR4 frame; 
     18        /** 
     19         * The frame pointed by this action. 
     20         */ 
     21        protected final ResourceRefR4 frame; 
    1622         
    1723        /** 
    1824         * Constructor. 
     
    2228                super(); 
    2329                this.frame = frame; 
    2430        } 
    25          
    26         public ResourceRefR4 getRef() { 
    27                 return this.frame; 
    28         } 
    29          
    30         /** 
    31          * Returns a new action with the desired ref.  
    32          * Override to provide a specific return type. 
    33          *   
    34          * @param ref 
    35          *                      The new {@link ResourceRefR4}. 
    36          * @return 
    37          *                      The new action. 
    38          */ 
    39         public abstract FrameShowingAction setRef(ResourceRefR4 ref); 
    4031 
    4132        @Override 
    4233        public int hashCode() { 
    4334                return super.hashCode() + (31 *  
    44                                 (getRef() == null ? 0 : getRef().hashCode())); 
     35                                (this.frame == null ? 0 : this.frame.hashCode())); 
    4536        } 
    4637         
    4738        @Override 
     
    5142                } 
    5243                 
    5344                FrameShowingAction action = (FrameShowingAction) obj; 
    54                 if (action.getRef() != null) { 
    55                         return action.getRef().equals(getRef()); 
     45                if (action.frame != null) { 
     46                        return action.frame.equals(this.frame); 
    5647                } 
    57                 return (action.getRef() == null) == (getRef() == null);  
     48                return (action.frame == null) == (this.frame == null);  
     49        } 
     50         
     51        public List<ResourceRefR4> getReferences() { 
     52                ArrayList<ResourceRefR4> res = new ArrayList<ResourceRefR4>(); 
     53                res.add(this.frame); 
     54                return res; 
    5855        } 
    5956         
    6057} 
  • src/main/java/org/sophie2/main/func/links/actions/showing/ShowFrameConfigurationPanel.java

     
    124124                                                && hud.holder().get() != null  
    125125                                                && hud.currentRule().get() != null 
    126126                                                && hud.currentRule().get().getAction() != null 
    127                                                 && hud.currentRule().get().getAction() instanceof FrameShowingAction 
    128                                                 && ((FrameShowingAction) hud.currentRule().get().getAction()).getRef() != null) { 
     127                                                && hud.currentRule().get().getAction() instanceof FrameShowingAction) { 
    129128                                        ResourceRefR4 selectedFrameRef = ((FrameShowingAction) hud.currentRule().get() 
    130                                                         .getAction()).getRef(); 
    131                                         absSelFrameRef = hud.holder().get().getRef().append(selectedFrameRef); 
     129                                                        .getAction()).getReferences().get(0); 
     130                                        if (selectedFrameRef != null) { 
     131                                                absSelFrameRef = hud.holder().get().getRef().append(selectedFrameRef); 
     132                                        } 
    132133                                } 
    133134                                         
    134135                                PageH page = pwa.getRootPageView().model().get(); 
  • src/main/java/org/sophie2/main/func/links/actions/navigation/GoToPageAction.java

     
    11package org.sophie2.main.func.links.actions.navigation; 
    22 
     3import java.util.ArrayList; 
     4import java.util.List; 
     5import java.util.Map; 
     6 
    37import org.sophie2.base.model.book.links.LinkAction; 
    48import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    5 import org.sophie2.base.model.resources.r4.immutables.ResourceRefWrapper; 
     9import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    610import org.sophie2.core.prolib.annot.Immutable; 
    711 
    812/** 
     
    1115 * @author kyli 
    1216 */ 
    1317@Immutable(kind="go-to-page-action") 
    14 public class GoToPageAction extends LinkAction implements ResourceRefWrapper { 
     18public class GoToPageAction extends LinkAction implements ResourceReferrer<GoToPageAction> { 
    1519 
    1620        private final ResourceRefR4 page; 
    1721         
     
    3337        @Override 
    3438        public int hashCode() { 
    3539                return super.hashCode() + (31 *  
    36                                 (getRef() == null ? 0 : getRef().hashCode())); 
     40                                (this.page == null ? 0 : this.page.hashCode())); 
    3741        } 
    3842         
    3943        @Override 
     
    4347                } 
    4448                 
    4549                GoToPageAction action = (GoToPageAction) obj; 
    46                 if (action.getRef() != null) { 
    47                         return action.getRef().equals(getRef()); 
     50                if (action.page != null) { 
     51                        return action.page.equals(this.page); 
    4852                } 
    49                 return (action.getRef() == null) == (getRef() == null);  
     53                return (action.page == null) == (this.page == null);  
    5054        } 
    5155 
    52         public ResourceRefR4 getRef() { 
    53                 return this.page; 
     56        public GoToPageAction fixReferences( 
     57                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     58                return new GoToPageAction(replaces.get(this.page)); 
    5459        } 
    5560 
    56         public ResourceRefWrapper setRef(ResourceRefR4 newRef) { 
    57                 return  new GoToPageAction(newRef); 
     61        public List<ResourceRefR4> getReferences() { 
     62                ArrayList<ResourceRefR4> res = new ArrayList<ResourceRefR4>(); 
     63                res.add(this.page); 
     64                return res; 
    5865        } 
    5966         
    6067} 
  • src/main/java/org/sophie2/main/func/links/persist/ToggleFrameActionPersister.java

     
    3434                ValueRef<ResourceRefR4> frame = new ValueRef<ResourceRefR4>() { 
    3535                        @Override 
    3636                        public ResourceRefR4 getInitial() { 
    37                                 return source.get().getRef(); 
     37                                return source.get().getReferences().get(0); 
    3838                        } 
    3939                }; 
    4040                 
  • src/main/java/org/sophie2/main/func/links/actions/showing/ShowFrameAction.java

     
    11package org.sophie2.main.func.links.actions.showing; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
     
    2628                return "Show frame"; 
    2729        } 
    2830         
    29         @Override 
    30         public ShowFrameAction setRef(ResourceRefR4 ref) { 
    31                 return new ShowFrameAction(ref); 
     31        public FrameShowingAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new ShowFrameAction(replaces.get(this.frame)); 
    3234        } 
    3335         
    3436} 
  • src/main/java/org/sophie2/main/func/links/persist/ShowFrameActionPersister.java

     
    3434                ValueRef<ResourceRefR4> frame = new ValueRef<ResourceRefR4>() { 
    3535                        @Override 
    3636                        public ResourceRefR4 getInitial() { 
    37                                 return source.get().getRef(); 
     37                                return source.get().getReferences().get(0); 
    3838                        } 
    3939                }; 
    4040                 
  • src/main/java/org/sophie2/main/func/links/actions/showing/HideFrameAction.java

     
    11package org.sophie2.main.func.links.actions.showing; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
    6  
    7  
    88/** 
    99 * Hides a frame. 
    1010 *  
     
    1212 */ 
    1313@Immutable(kind="hide-frame-action") 
    1414public class HideFrameAction extends FrameShowingAction { 
    15          
     15 
    1616        /** 
    1717         * Default constructor. 
    1818         *  
     
    2828                return "Hide frame"; 
    2929        } 
    3030 
    31         @Override 
    32         public HideFrameAction setRef(ResourceRefR4 ref) { 
    33                 return new HideFrameAction(ref); 
     31        public FrameShowingAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new HideFrameAction(replaces.get(this.frame)); 
    3434        } 
    35          
     35 
    3636} 
  • src/main/java/org/sophie2/main/func/links/actions/showing/ToggleFrameAction.java

     
    11package org.sophie2.main.func.links.actions.showing; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
     
    2628                return "Toggle frame"; 
    2729        } 
    2830 
    29         @Override 
    30         public ToggleFrameAction setRef(ResourceRefR4 ref) { 
    31                 return new ToggleFrameAction(ref); 
     31        public FrameShowingAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new ToggleFrameAction(replaces.get(this.frame)); 
    3234        } 
    33          
    3435} 
  • src/main/java/org/sophie2/main/func/links/actions/navigation/GoToPageConfigurationPanel.java

     
    122122                                        && hud.holder().get() != null  
    123123                                        && hud.currentRule().get() != null 
    124124                                        && hud.currentRule().get().getAction() != null 
    125                                         && hud.currentRule().get().getAction() instanceof GoToPageAction 
    126                                         && ((GoToPageAction) hud.currentRule().get().getAction()).getRef() != null) { 
    127                                 ResourceRefR4 rulePageRef =  
    128                                         ((GoToPageAction) hud.currentRule().get().getAction()).getRef(); 
    129                                 absRulePageRef = hud.holder().get().getRef().append(rulePageRef); 
     125                                        && hud.currentRule().get().getAction() instanceof GoToPageAction){ 
     126                                ResourceRefR4 rulePageRef = ((GoToPageAction) hud.currentRule().get().getAction() 
     127                                                                                                                        ).getReferences().get(0); 
     128                                 
     129                                if (rulePageRef != null) {  
     130                                        absRulePageRef = hud.holder().get().getRef().append(rulePageRef); 
     131                                } 
    130132                        } 
    131133                        PageH rulePage = null; 
    132134                        BookH book = bv.model().get(); 
  • src/main/java/org/sophie2/main/func/links/persist/HideFrameActionPersister.java

     
    3434                ValueRef<ResourceRefR4> frame = new ValueRef<ResourceRefR4>() { 
    3535                        @Override 
    3636                        public ResourceRefR4 getInitial() { 
    37                                 return source.get().getRef(); 
     37                                return source.get().getReferences().get(0); 
    3838                        } 
    3939                }; 
    4040                 
  • src/main/java/org/sophie2/main/func/links/actions/showing/ShowingActionLogic.java

     
    141141                ResourceAccess access = event.getEventParam( 
    142142                                LinkEvent.RESOURCE_ACCESS_PARAM_INDEX, ResourceAccess.class); 
    143143                 
    144                 ResourceRefR4 frameRef = action.getRef(); 
     144                ResourceRefR4 frameRef = action.getReferences().get(0); 
    145145                if (frameRef == null) { 
    146146                        return null; 
    147147                } 
  • src/main/java/org/sophie2/main/func/media/links/StopMediaActionPersister.java

    #P org.sophie2.main.func.media
     
    3232                 
    3333                ValueRef<ResourceRefR4> frameRef = new ValueRef<ResourceRefR4>(); 
    3434                if (options.isSaveMode()) { 
    35                         frameRef.set(source.get().getRef()); 
     35                        frameRef.set(source.get().getReferences().get(0)); 
    3636                } 
    3737                 
    3838                MasterPersister.persist(frameRef, target.child("frame"),  
  • src/main/java/org/sophie2/main/func/media/links/RewindMediaActionPersister.java

     
    3232                 
    3333                ValueRef<ResourceRefR4> frameRef = new ValueRef<ResourceRefR4>(); 
    3434                if (options.isSaveMode()) { 
    35                         frameRef.set(source.get().getRef()); 
     35                        frameRef.set(source.get().getReferences().get(0)); 
    3636                } 
    3737                 
    3838                MasterPersister.persist(frameRef, target.child("frame"),  
  • src/main/java/org/sophie2/main/func/media/links/MediaPlayAction.java

     
    11package org.sophie2.main.func.media.links; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
     
    2527        public String getDescription() { 
    2628                return "Play Media"; 
    2729        } 
    28         @Override 
    29         public MediaPlayAction setRef(ResourceRefR4 newRef) { 
    30                 return  new MediaPlayAction(newRef); 
     30 
     31        public MediaPlayAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new MediaPlayAction(replaces.get(this.mediaFrame)); 
    3134        } 
    3235         
    3336} 
     37 No newline at end of file 
  • src/main/java/org/sophie2/main/func/media/links/MediaStopAction.java

     
    11package org.sophie2.main.func.media.links; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
     
    2527        public String getDescription() { 
    2628                return "Stop Media"; 
    2729        } 
    28         @Override 
    29         public MediaStopAction setRef(ResourceRefR4 newRef) { 
    30                 return  new MediaStopAction(newRef); 
     30 
     31        public MediaStopAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new MediaStopAction(replaces.get(this.mediaFrame)); 
    3134        } 
    32          
     35                 
    3336} 
  • src/main/java/org/sophie2/main/func/media/links/PlayMediaActionPersister.java

     
    3232                 
    3333                ValueRef<ResourceRefR4> frameRef = new ValueRef<ResourceRefR4>(); 
    3434                if (options.isSaveMode()) { 
    35                         frameRef.set(source.get().getRef()); 
     35                        frameRef.set(source.get().getReferences().get(0)); 
    3636                } 
    3737                 
    3838                MasterPersister.persist(frameRef, target.child("frame"),  
  • src/main/java/org/sophie2/main/func/media/links/PauseMediaActionPersister.java

     
    3232                 
    3333                ValueRef<ResourceRefR4> frameRef = new ValueRef<ResourceRefR4>(); 
    3434                if (options.isSaveMode()) { 
    35                         frameRef.set(source.get().getRef()); 
     35                        frameRef.set(source.get().getReferences().get(0)); 
    3636                } 
    3737                 
    3838                MasterPersister.persist(frameRef, target.child("frame"),  
  • src/main/java/org/sophie2/main/func/media/links/MediaConfigurationPanelsLogic.java

     
    11package org.sophie2.main.func.media.links; 
    22 
     3import java.util.HashMap; 
     4import java.util.Map; 
     5 
    36import org.sophie2.base.bound.ComboInput; 
    47import org.sophie2.base.bound.BoundControl.EventIds; 
    58import org.sophie2.base.model.book.links.LinkRule; 
     
    4952                                                ResourceRefR4.getRelativeRef(holder.getRef(), targetFrame.getRef()); 
    5053                                         
    5154                                        assert currentRule.getAction() instanceof MediaAction; 
    52                                          
    53                                         MediaAction newAction = ( 
    54                                                         (MediaAction)currentRule.getAction()).setRef(newRef); 
     55                                        Map<ResourceRefR4, ResourceRefR4> replaces = new HashMap<ResourceRefR4, ResourceRefR4>(); 
     56                                        MediaAction oldAction = (MediaAction)currentRule.getAction(); 
     57                                        replaces.put(oldAction.getReferences().get(0), newRef); 
     58                                        MediaAction newAction = oldAction.fixReferences(replaces); 
    5559                                         
    5660                                        LinksUtil.addAction(hud, newAction); 
    5761                                } 
  • src/main/java/org/sophie2/main/func/media/links/MediaActionConfigurationPanel.java

     
    120120                                                && hud.holder().get() != null  
    121121                                                && hud.currentRule().get() != null 
    122122                                                && hud.currentRule().get().getAction() != null 
    123                                                 && hud.currentRule().get().getAction() instanceof MediaAction 
    124                                                 && ((MediaAction) hud.currentRule().get().getAction()).getRef() != null) { 
     123                                                && hud.currentRule().get().getAction() instanceof MediaAction) { 
    125124                                        ResourceRefR4 selectedFrameRef = ((MediaAction) hud.currentRule().get() 
    126                                                         .getAction()).getRef(); 
    127                                         absSelFrameRef = hud.holder().get().getRef().append(selectedFrameRef); 
     125                                                        .getAction()).getReferences().get(0); 
     126                                        if (selectedFrameRef != null) { 
     127                                                absSelFrameRef = hud.holder().get().getRef().append(selectedFrameRef); 
     128                                        } 
    128129                                } 
    129130                                         
    130131                                PageH page = pwa.getRootPageView().model().get(); 
  • src/main/java/org/sophie2/main/func/media/links/MediaRewindAction.java

     
    11package org.sophie2.main.func.media.links; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
     
    2527        public String getDescription() { 
    2628                return "Rewind Media"; 
    2729        } 
    28         @Override 
    29         public MediaRewindAction setRef(ResourceRefR4 newRef) { 
    30                 return  new MediaRewindAction(newRef); 
     30 
     31        public MediaRewindAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new MediaRewindAction(replaces.get(this.mediaFrame)); 
    3134        } 
    3235         
    3336} 
     37 No newline at end of file 
  • src/main/java/org/sophie2/main/func/media/links/MediaAction.java

     
    11package org.sophie2.main.func.media.links; 
    22 
     3import java.util.ArrayList; 
     4import java.util.List; 
     5 
    36import org.sophie2.base.model.book.links.LinkAction; 
    47import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    5 import org.sophie2.base.model.resources.r4.immutables.ResourceRefWrapper; 
     8import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    69import org.sophie2.main.func.media.model.contents.MediaFrameR4; 
    710 
    811/** 
     
    1013 *  
    1114 * @author diana 
    1215 */ 
    13 public abstract class MediaAction extends LinkAction implements ResourceRefWrapper { 
     16public abstract class MediaAction extends LinkAction  
     17                                                                implements ResourceReferrer<MediaAction> { 
    1418         
    15         private final ResourceRefR4 mediaView; 
     19        /** 
     20         * Ref to the controlled media frame. 
     21         */ 
     22        protected final ResourceRefR4 mediaFrame; 
    1623 
    1724        /** 
    1825         * Constructor of the class. 
     
    2128         *                 The reference to the controlled {@link MediaFrameR4}. 
    2229         */ 
    2330        public MediaAction(ResourceRefR4 mediaViewRef) { 
    24                 this.mediaView = mediaViewRef; 
     31                this.mediaFrame = mediaViewRef; 
    2532        } 
    2633         
    2734 
    2835        @Override 
    2936        public int hashCode() { 
    3037                return super.hashCode() + (31 *  
    31                                 (getRef() == null ? 0 : getRef().hashCode())); 
     38                                (this.mediaFrame == null ? 0 : this.mediaFrame.hashCode())); 
    3239        } 
    3340 
    3441        @Override 
     
    3845                } 
    3946 
    4047                MediaAction action = (MediaAction) obj; 
    41                 if (action.getRef() != null) { 
    42                         return action.getRef().equals(getRef()); 
     48                if (action.mediaFrame != null) { 
     49                        return action.mediaFrame.equals(this.mediaFrame); 
    4350                } 
    44                 return (action.getRef() == null) == (getRef() == null);  
     51                return (action.mediaFrame == null) == (this.mediaFrame == null);  
    4552        } 
    46         public ResourceRefR4 getRef() { 
    47                 return this.mediaView; 
     53         
     54        public List<ResourceRefR4> getReferences() { 
     55                ArrayList<ResourceRefR4> res = new ArrayList<ResourceRefR4>(); 
     56                res.add(this.mediaFrame); 
     57                return res; 
    4858        } 
    49         public abstract MediaAction setRef(ResourceRefR4 ref); 
     59 
    5060} 
  • src/main/java/org/sophie2/main/func/media/links/MediaActionLogic.java

     
    170170                ResourceAccess access = event.getEventParam( 
    171171                                LinkEvent.RESOURCE_ACCESS_PARAM_INDEX, ResourceAccess.class); 
    172172 
    173                 ResourceRefR4 mediaFrameRef = action.getRef(); 
     173                ResourceRefR4 mediaFrameRef = action.getReferences().get(0); 
    174174                if (mediaFrameRef == null) { 
    175175                        return null; 
    176176                } 
  • src/main/java/org/sophie2/main/func/media/links/MediaPauseAction.java

     
    11package org.sophie2.main.func.media.links; 
    22 
     3import java.util.Map; 
     4 
    35import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    46import org.sophie2.core.prolib.annot.Immutable; 
    57 
     
    2527        public String getDescription() { 
    2628                return "Pause Media"; 
    2729        } 
    28          
    29         @Override 
    30         public MediaPauseAction setRef(ResourceRefR4 newRef) { 
    31                 return  new MediaPauseAction(newRef); 
     30 
     31        public MediaPauseAction fixReferences( 
     32                        Map<ResourceRefR4, ResourceRefR4> replaces) { 
     33                return new MediaPauseAction(replaces.get(this.mediaFrame)); 
    3234        } 
    3335         
    3436} 
  • src/main/java/org/sophie2/base/model/book/links/Link.java

    #P org.sophie2.base.model.book
     
    11package org.sophie2.base.model.book.links; 
    22 
     3import java.util.ArrayList; 
     4import java.util.List; 
     5import java.util.Map; 
     6 
    37import org.sophie2.base.commons.util.ImmList; 
    48import org.sophie2.base.commons.util.NaiveImmList; 
    5 import org.sophie2.base.model.resources.r4.ResourceRefList; 
    69import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    7 import org.sophie2.base.model.resources.r4.immutables.ResourceRefHolder; 
    8 import org.sophie2.base.model.resources.r4.immutables.ResourceRefWrapper; 
     10import org.sophie2.base.model.resources.r4.model.ResourceReferrer; 
    911import org.sophie2.core.prolib.annot.Immutable; 
    1012 
    1113/** 
     
    1416 * @author boyan 
    1517 */ 
    1618@Immutable(kind="link") 
    17 public class Link implements ResourceRefHolder { 
    18          
     19public class Link implements ResourceReferrer<Link> { 
     20 
    1921        /** 
    2022         * A link with no parent resource and no rules. 
    2123         */ 
     
    3638        public Link(ImmList<LinkRule> rules) { 
    3739                this(rules, false); 
    3840        } 
    39          
     41 
    4042        private Link(ImmList<LinkRule> rules, boolean visited) { 
    4143                this.rules = rules; 
    4244                this.visited = visited; 
     
    7476        public Link setVisited(boolean visited) { 
    7577                return new Link(this.rules, visited); 
    7678        } 
    77          
     79 
    7880        /** 
    7981         * Checks whether this Link has been visited,  
    8082         * i.e. at least one of its actions has been executed at least once.  
     
    8587        public boolean isVisited() { 
    8688                return this.visited; 
    8789        } 
    88  
    89         public ResourceRefList getRefs() { 
    90                 ResourceRefList res = ResourceRefList.EMPTY; 
     90         
     91        public List<ResourceRefR4> getReferences() { 
     92                List<ResourceRefR4> res = new ArrayList<ResourceRefR4>(); 
    9193                for (LinkRule rule : getRules()) { 
    9294                        LinkAction action = rule.getAction(); 
    93                         if (action instanceof ResourceRefWrapper) { 
    94                                 ResourceRefR4 ref = ((ResourceRefWrapper)action).getRef(); 
    95                                 res = res.add(ref); 
    96                         } else { 
    97                                 res = res.add(ResourceRefR4.NONE_REF); 
     95                        if (action instanceof ResourceReferrer<?>) { 
     96                                res.addAll(((ResourceReferrer<?>)action).getReferences()); 
    9897                        } 
    9998                } 
    10099                return res; 
    101100        } 
    102101 
    103         public ResourceRefHolder rewriteRefs(ResourceRefList rewritenRefs) { 
    104                 ImmList<LinkRule> newRules = NaiveImmList.<LinkRule>getEmpty(); 
    105                 for (int i = 0; i < this.rules.size(); i++) { 
    106                         LinkRule rule = this.rules.get(i); 
     102        public Link fixReferences(Map<ResourceRefR4, ResourceRefR4> replaces) { 
     103                ImmList<LinkRule> newRules = this.rules; 
     104                for (int i = 0; i < newRules.size(); i++) { 
     105                        LinkRule rule  =  newRules.get(i); 
    107106                        LinkAction action = rule.getAction(); 
    108                         if (action instanceof ResourceRefWrapper) { 
    109                                 ResourceRefWrapper wrapper = (ResourceRefWrapper)action; 
    110                                 LinkAction rewritenAction = (LinkAction) 
    111                                         wrapper.setRef(rewritenRefs.get(i)); 
    112                                 newRules = newRules.add( 
    113                                                 new LinkRule(rule.getTrigger(), rewritenAction)); 
    114                         } else { 
    115                                 newRules = newRules.add(rule); 
     107                        if (action instanceof ResourceReferrer<?>) { 
     108                                ResourceReferrer<?> referrerer = (ResourceReferrer<?>)action; 
     109                                List<ResourceRefR4> refs = referrerer.getReferences(); 
     110                                assert (refs.size() == 1) : "The action should have only one ref"; 
     111                                ResourceRefR4 replaceRef = replaces.get(refs.get(0)); 
     112                                if (replaceRef != null) { 
     113                                        LinkAction rewritenAction = (LinkAction) referrerer.fixReferences(replaces); 
     114                                        newRules = newRules.set(i, new LinkRule(rule.getTrigger(), rewritenAction)); 
     115                                } 
     116 
    116117                        } 
    117118                } 
    118119                return new Link(newRules); 
    119120        } 
     121 
    120122} 
  • src/main/java/org/sophie2/base/model/book/BookH.java

     
    44import java.util.List; 
    55import java.util.Map; 
    66 
     7import org.sophie2.base.commons.structures.ImmTreeList; 
    78import org.sophie2.base.commons.util.ImmList; 
    89import org.sophie2.base.commons.util.position.ImmSize; 
    910import org.sophie2.base.model.book.resource.AudioResourceH; 
     
    4546         */ 
    4647        @SuppressWarnings("hiding") 
    4748        public static final String NAME_PREFIX = "book"; 
     49 
     50        /** 
     51         * A list of keys that point to its sub-elements. 
     52         */ 
     53        @SuppressWarnings("unchecked") 
     54        public static final List<Key<ResourceRefList>> SUBELEMENTS_KEYS = ImmTreeList.create( 
     55                        BookR4.KEY_PAGES, BookR4.KEY_FRAME_TEMPLATES, BookR4.KEY_PAGE_TEMPLATES).asList(); 
    4856         
    4957        /** 
    5058         * Default constructor with {@link ResourceAccess}. 
     
    364372                        ResourceRefList curPages) { 
    365373                assert BookR4.KEY_PAGES.getMode(bookChanger) != TemplatedKey.Mode.LOCKED : "Not modifiable"; 
    366374                 
    367                 bookChanger.setRaw(BookR4.KEY_PAGES, (ResourceRefList) curPages.remove(pageRef)); 
     375                bookChanger.setRaw(BookR4.KEY_PAGES, curPages.remove(pageRef)); 
    368376                bookChanger.removeResource(pageRef); 
    369377        } 
    370378 
  • src/main/java/org/sophie2/main/app/layout/right/library/LibraryTabLogic.java

    #P org.sophie2.main.app.layout
     
    163163                                        @Override 
    164164                                        public void performAuto() { 
    165165                                                ResourceRefList templates = getChanger().getRaw(BookR4.KEY_FRAME_TEMPLATES); 
    166                                                 templates = (ResourceRefList) templates.remove(relativeRef); 
     166                                                templates = templates.remove(relativeRef); 
    167167                                                getChanger().setRaw(BookR4.KEY_FRAME_TEMPLATES, templates); 
    168168                                        } 
    169169                                }.register(bookDocView.getAccess()); 
     
    354354                                        @Override 
    355355                                        public void performAuto() { 
    356356                                                ResourceRefList templates = getChanger().getRaw(BookR4.KEY_PAGE_TEMPLATES); 
    357                                                 templates = (ResourceRefList) templates.remove(relativeRef); 
     357                                                templates = templates.remove(relativeRef); 
    358358                                                getChanger().setRaw(BookR4.KEY_PAGE_TEMPLATES, templates); 
    359359                                        } 
    360360                                }.register(bookDocView.getAccess());