Ticket #2427: actions2.patch

File actions2.patch, 134.1 KB (added by meddle, 15 years ago)

Second patch

  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/RemoveResourceAction.java

    ### Eclipse Workspace Patch 1.0
    #P sophie
     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     4import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     5import org.sophie2.base.skins.Message; 
     6 
     7/** 
     8 * {@link AutoAction} for deleting a resource. 
     9 *  
     10 * @author diana 
     11 */ 
     12public class RemoveResourceAction extends AutoAction { 
     13         
     14        private final ResourceRefR4 resourceRef; 
     15 
     16        /** 
     17         * Creates the action with the reference to the resource to delete. 
     18         *  
     19         * @param description  
     20         *                      Description of the action.  
     21         * @param significant  
     22         *                      Significance of the action.  
     23         * @param resourceRef 
     24         *                      {@link ResourceRefR4} pointing to the resource to delete. 
     25         */ 
     26        public RemoveResourceAction(Message description, boolean significant, 
     27                        ResourceRefR4 resourceRef) { 
     28                super(description, significant); 
     29                 
     30                this.resourceRef = resourceRef; 
     31        } 
     32 
     33        @Override 
     34        public void performAuto() { 
     35                getChanger().removeResource(this.resourceRef); 
     36        } 
     37} 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/ApplyTemplateAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.commons.util.NaiveImmList; 
     4import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     5import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     6import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 
     7import org.sophie2.base.skins.Message; 
     8import org.sophie2.main.app.commons.util.TemplateUtil; 
     9 
     10/** 
     11 * {@link AutoAction} for applying a template to a resource. 
     12 *  
     13 * @author deni 
     14 */ 
     15public class ApplyTemplateAction extends AutoAction { 
     16         
     17        private final NaiveImmList<TemplatedKey<?>> immKeys; 
     18        private final ResourceRefR4 templateRef; 
     19        private final String kind; 
     20 
     21        /** 
     22         * Creates the action with all the needed information for applying a 
     23         * template to a resource. 
     24         *  
     25         * @param description  
     26         *                      Description of the action.  
     27         * @param significant  
     28         *                      Significance of the action.  
     29         * @param immKeys 
     30         *                      The templated keys of the resource. 
     31         * @param templateRef 
     32         *                      The reference to the template to apply. 
     33         * @param kind 
     34         *                      The kind of the template. 
     35         */ 
     36        public ApplyTemplateAction(Message description, boolean significant, 
     37                        NaiveImmList<TemplatedKey<?>> immKeys, 
     38                        ResourceRefR4 templateRef, String kind) { 
     39                super(description, significant); 
     40                 
     41                this.immKeys = immKeys; 
     42                this.templateRef = templateRef; 
     43                this.kind = kind; 
     44        } 
     45 
     46        @Override 
     47        public void performAuto() { 
     48                TemplateUtil.applyFrameTemplate(getChanger(),  
     49                                this.immKeys.asList(),  
     50                                this.templateRef, false, this.kind, true); 
     51 
     52        } 
     53} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/imports/ResourceImportUtilTest.java

     
    88 
    99import org.junit.Before; 
    1010import org.junit.Test; 
     11import org.sophie2.base.bound.BoundModule; 
    1112import org.sophie2.base.commons.BaseCommonsModule; 
    1213import org.sophie2.base.commons.util.position.ImmPoint; 
     14import org.sophie2.base.config.BaseConfigModule; 
    1315import org.sophie2.base.dialogs.BaseDialogsModule; 
    1416import org.sophie2.base.dialogs.TestingDialogManager; 
    1517import org.sophie2.base.dnd.DndData; 
     
    2830import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 
    2931import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    3032import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
     33import org.sophie2.base.persistence.BasePersistenceModule; 
    3134import org.sophie2.base.skins.BaseSkinsModule; 
    3235import org.sophie2.base.skins.Message; 
    3336import org.sophie2.base.visual.BaseVisualModule; 
     
    4144import org.sophie2.main.dialogs.input.file.FileDialogInput; 
    4245import org.sophie2.main.dialogs.input.file.FileFilterInfo; 
    4346import org.sophie2.main.func.file.FileFunctionalityModule; 
     47import org.sophie2.main.func.resources.actions.CreateColdTextAction; 
    4448import org.sophie2.main.func.resources.dummy.ColdTextData; 
    4549import org.sophie2.main.func.resources.dummy.ColdTextFrame; 
    4650import org.sophie2.main.func.resources.dummy.ColdTextImportManager; 
     
    117121        protected List<Class<? extends SophieModule>> fillDependencies() { 
    118122                return Arrays.asList(BaseModelResourcesR4Module.class, 
    119123                                BaseVisualModule.class, BaseMediaModule.class, 
    120                                 BaseCommonsModule.class, MainMediaNatlibModule.class, 
    121                                 BaseDialogsModule.class, BaseSkinsModule.class, 
    122                                 BaseModelBookModule.class, FileFunctionalityModule.class, 
    123                                 MainAppModule.class, 
     124                                BaseConfigModule.class, BasePersistenceModule.class, 
     125                                BaseCommonsModule.class, BoundModule.class,  
     126                                MainMediaNatlibModule.class, BaseDialogsModule.class,  
     127                                BaseSkinsModule.class, BaseModelBookModule.class,  
     128                                FileFunctionalityModule.class, MainAppModule.class, 
    124129                                ColdTextModule.class); 
    125130        } 
    126131         
     
    275280                        ResourceRefR4.generateRandomSub(ColdTextResource.DEFAULT_TITLE); 
    276281                final String text = "My text"; 
    277282                 
    278                 new AutoAction(Message.create(CREATING_COLD_TEXT), true) { 
    279                         @Override 
    280                         public void performAuto() { 
    281                                 ColdTextResourceHelper.createColdText(getChanger(), 
    282                                                 coldRef, text); 
    283                          
    284                         } 
    285                 }.register(bookAccess); 
     283                Message description = Message.create(CREATING_COLD_TEXT); 
     284                AutoAction action = new CreateColdTextAction(description, true, text, coldRef); 
     285                action.register(bookAccess); 
    286286                 
    287287                // text and page: 
    288288                assertEquals(2, book.getChildren().size()); 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/SetFrameResourceAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.model.book.interfaces.ResourceFrame; 
     4import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     5import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     6import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
     7import org.sophie2.base.skins.Message; 
     8 
     9/** 
     10 * {@link AutoAction} for changing the main resource of a frame. 
     11 *  
     12 * @author deni 
     13 */ 
     14public class SetFrameResourceAction extends AutoAction { 
     15         
     16        private final ResourceRefR4 relRef; 
     17        private final String newFrameKind; 
     18 
     19        /** 
     20         * Creates the action with a relative {@link ResourceRefR4} from the frame to 
     21         * the new main resource and new kind of the frame, corresponding to the resource. 
     22         *  
     23         * @param description  
     24         *                      Description of the action.  
     25         * @param significant  
     26         *                      Significance of the action.  
     27         * @param relRef 
     28         *                      Reference from the frame to the new main resource. 
     29         * @param newFrameKind 
     30         *                      The new frame kind, according to the new main resource. 
     31         */ 
     32        public SetFrameResourceAction(Message description, boolean significant, 
     33                        ResourceRefR4 relRef, String newFrameKind) { 
     34                super(description, significant); 
     35                 
     36                this.relRef = relRef; 
     37                this.newFrameKind = newFrameKind; 
     38        } 
     39 
     40        @Override 
     41        public void performAuto() { 
     42                getChanger().setRaw(ResourceR4.KEY_KIND, this.newFrameKind); 
     43                getChanger().setRaw(ResourceFrame.KEY_MAIN_RESOURCE, this.relRef); 
     44        } 
     45} 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/imports/ResourceImportUtil.java

     
    1 package org.sophie2.main.func.resources.imports; 
    2  
    3 import java.io.BufferedInputStream; 
    4 import java.io.BufferedOutputStream; 
    5 import java.io.File; 
    6 import java.io.FileOutputStream; 
    7 import java.io.IOException; 
    8 import java.io.InputStream; 
    9 import java.io.OutputStream; 
    10 import java.util.Enumeration; 
    11 import java.util.LinkedList; 
    12 import java.util.List; 
    13 import java.util.zip.ZipEntry; 
    14 import java.util.zip.ZipFile; 
    15  
    16 import org.sophie2.base.commons.util.ImmList; 
    17 import org.sophie2.base.commons.util.NaiveImmList; 
    18 import org.sophie2.base.commons.util.position.ImmPoint; 
    19 import org.sophie2.base.commons.util.position.ImmSize; 
    20 import org.sophie2.base.dialogs.DialogManager; 
    21 import org.sophie2.base.dnd.DndTransferable; 
    22 import org.sophie2.base.model.book.BookH; 
    23 import org.sophie2.base.model.book.ElementH; 
    24 import org.sophie2.base.model.book.FrameH; 
    25 import org.sophie2.base.model.book.frame.FrameR4; 
    26 import org.sophie2.base.model.book.interfaces.CompositeElement; 
    27 import org.sophie2.base.model.book.resource.ResourceFilesUtil; 
    28 import org.sophie2.base.model.book.timelines.ActivationChannel; 
    29 import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    30 import org.sophie2.base.model.resources.r4.ResourceUtil; 
    31 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    32 import org.sophie2.base.model.resources.r4.changes.AutoAction; 
    33 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 
    34 import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 
    35 import org.sophie2.base.model.resources.r4.model.ResourceModel; 
    36 import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    37 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
    38 import org.sophie2.base.skins.Message; 
    39 import org.sophie2.core.logging.SophieLog; 
    40 import org.sophie2.main.app.commons.util.TemplateUtil; 
    41 import org.sophie2.main.dialogs.input.DialogUtils; 
    42 import org.sophie2.main.dialogs.input.MessageDialogInput; 
    43 import org.sophie2.main.dialogs.input.MessageDialogInput.MessageType; 
    44 import org.sophie2.main.dialogs.input.file.FileDialogInput; 
    45 import org.sophie2.main.func.resources.imports.bindata.ResourceImportType; 
    46  
    47 /** 
    48  * Used to import different resources that are registered 
    49  * to be import-able.  
    50  *  
    51  * @author meddle 
    52  */ 
    53 public final class ResourceImportUtil { 
    54  
    55         /** 
    56          * The provider used to open resources in Sophie Format. 
    57          * It is not registered as an extension and is used for 
    58          * handling import of any resource that is in Sophie 2.0 format.  
    59          */ 
    60         public static final ResourceImportProvider SOPHIE_FORMAT_PROVIDER =  
    61                 new SimpleResourceImportProvider(new SophieFormatImportManager(), FileDialogInput.BOOK_FILTER); 
    62  
    63         /** 
    64          * Imports a resource in the passed book, without inserting a frame 
    65          * for it.  
    66          *  
    67          * @param <D> 
    68          *                      The data used to create the resource. 
    69          * @param provider 
    70          *                      The {@link ResourceImportProvider} of the resource to insert. 
    71          * @param book 
    72          *                      The book in which the resource will be inserted. 
    73          * @param resFile 
    74          *                      The file from which the resource is imported.  
    75          * @return 
    76          *                      True if the resource is inserted. 
    77          */ 
    78         @SuppressWarnings("unchecked") 
    79         public static <D> ResourceRefR4 importResource(ResourceImportProvider provider, 
    80                         ResourceH book, File resFile) { 
    81                 final ResourceImportManager<D> importManager =  
    82                         (ResourceImportManager<D>) provider.getImportManager(); 
    83  
    84                 D data =  
    85                         importManager.getResourceData(resFile, book); 
    86  
    87                 if (data == null) { 
    88                         return null; 
    89                 } 
    90  
    91                 final ResourceRefR4 resourceRef = importManager.generateChildRef(); 
    92  
    93                 final ResourceImportInfo<D> importInfo =  
    94                         new ResourceImportInfo<D>(data, resFile.getName(), resFile.toURI(), 
    95                                         ResourceImportType.EMBED); 
    96  
    97                 // The description must be smarter... May be with skins --meddle 2009-10-21 
    98                 new AutoAction(Message.create(IMPORT_RES, importInfo.getName()), true) { 
    99                         @Override 
    100                         public void performAuto() { 
    101                                 ResourceChanger changer = getChanger(); 
    102  
    103                                 importManager.makeResource(changer, resourceRef, importInfo); 
    104  
    105                         } 
    106                 }.register(book.getAccess()); 
    107  
    108                 return resourceRef; 
    109         }        
    110          
    111         /** 
    112          * Imports the Sophie2 resource carried by the given transferable in the current book. 
    113          *  
    114          * @param book 
    115          *              The book in which the resource will be inserted. 
    116          * @param transferable 
    117          *              The transferable carrying the resource to import. 
    118          * @param significant 
    119          *              Whether the AutoAction should be registered as significant. 
    120          * @return 
    121          *              An absolute reference to the imported resource or null if no resource was imported. 
    122          */ 
    123         @SuppressWarnings("unchecked") 
    124         public static ResourceRefR4 importResource(BookH book, DndTransferable transferable, 
    125                         boolean significant) { 
    126                  
    127                 final ResourceImportManager<?> importManager =  
    128                         ResourceImportUtil.SOPHIE_FORMAT_PROVIDER.getImportManager(); 
    129                 ResourceModel data = (ResourceModel) importManager.getResourceData(transferable); 
    130                 if (data == null) { 
    131                         return null; 
    132                 } 
    133                  
    134                 String title = data.getRaw(ResourceR4.KEY_TITLE); 
    135                 final ResourceImportInfo importInfo = new ResourceImportInfo(data, title); 
    136                 final ResourceRefR4 childRef = importManager.generateChildRef(); 
    137                  
    138                 new AutoAction(Message.create(IMPORT_RES, importInfo.getName()), significant) { 
    139                         @Override 
    140                         public void performAuto() { 
    141  
    142                                 importManager.makeResource(getChanger(), childRef, importInfo); 
    143  
    144                         } 
    145                 }.register(book.getAccess()); 
    146                  
    147                 return book.getRef().append(childRef); 
    148         } 
    149          
    150         /** 
    151          * Constant created for importing resources by resource name. 
    152          * Constant created to be a parameter of a message of an {@link AutoAction}.  
    153          * Used for skinning. 
    154          */ 
    155         public final static String IMPORT_RES = "Import resource %1$s."; 
    156  
    157         private static <D> void insert(final ResourceImportInfo<D> importInfo, 
    158                         final ResourceImportManager<D> importManager, BookH book, 
    159                         ElementH parent, final ResourceRefR4 parentRef, 
    160                         final ResourceRefR4 resourceRef, 
    161                         final ImmPoint pos) { 
    162  
    163                 assert importInfo != null : "Resource data can not be null!"; 
    164  
    165                 final ResourceRefR4 frameRef =  
    166                         ResourceRefR4.generateRandomSub(FrameH.NAME_PREFIX); 
    167  
    168                 // Prepare data for the frame to insert. 
    169                 final ImmSize frameSize =  
    170                         importManager.computeFrameSize(importInfo.getData());    
    171  
    172                 final String frameTitle =  
    173                         importInfo.getName() + " " + FrameR4.DEFAULT_TITLE; 
    174  
    175                 final ImmList<ActivationChannel> elements =  
    176                         CompositeElement.KEY_SUB_ELEMENTS.get(parent.getAccess()); 
    177                 ResourceRefR4 defaultTemplate = book.getDefaultFrameTemplate(); 
    178                 final boolean isDefaultTemplate = ! defaultTemplate.equals(ResourceRefR4.NONE_REF); 
    179                 final boolean linked = importInfo.isModelLinked();  
    180  
    181  
    182                 // The description must be smarter... May be with skins --meddle 2009-10-21 
    183                 new AutoAction(Message.create(INSERT_FRAME_FOR_RESOURCE, importInfo.getName()), true) { 
    184                         @Override 
    185                         public void performAuto() { 
    186                                 ResourceChanger changer = getChanger(); 
    187                                 if (!linked) { 
    188                                         importManager.makeResource(changer, resourceRef, importInfo); 
    189                                 } 
    190  
    191                                 importManager.insertFrame(changer.getSub(parentRef), 
    192                                                 parentRef, frameRef, resourceRef, frameTitle, 
    193                                                 elements, pos, frameSize); 
    194  
    195                         } 
    196                 }.register(book.getAccess()); 
    197                  
    198                 if (isDefaultTemplate) { 
    199                         ResourceRefR4 absoluteDefRef = book.getRef().getAbsolute(defaultTemplate); 
    200                         ResourceRefR4 absoluteFrameRef = parent.getRef().getAbsolute(frameRef); 
    201                          
    202                         assert absoluteDefRef.isAbsolute(); 
    203                         final ResourceRefR4 templateRef = ResourceRefR4.getRelativeRef(absoluteFrameRef, 
    204                                         absoluteDefRef); 
    205  
    206                         ResourceAccess templateAccess = book.getAccess().open(absoluteDefRef , null); 
    207  
    208                         ResourceAccess frameAccess = parent.getAccess().open(frameRef, null); 
    209                         final String kind = templateAccess.getRaw(ResourceR4.KEY_KIND); 
    210  
    211                         FrameH templateH = ResourceH.getHelper(templateAccess, FrameH.class); 
    212                         final NaiveImmList<TemplatedKey<?>> immKeys = templateH.getApplicableTemplatedKeys(); 
    213  
    214                         new AutoAction(Message.create(APPLY_TEMPLATE_FOR_RESOURCE, importInfo.getName()), false) { 
    215                                 @Override 
    216                                 public void performAuto() { 
    217                                         TemplateUtil.applyFrameTemplate(getChanger(),  
    218                                                         immKeys.asList(),  
    219                                                         templateRef, false, kind, true); 
    220  
    221                                 } 
    222                         }.register(frameAccess); 
    223                 } 
    224         } 
    225          
    226         /** 
    227          * Constant created for inserting frame for resource by name. 
    228          * Constant created to be a parameter of a message of an {@link AutoAction}.  
    229          * Used for skinning. 
    230          */ 
    231         public static final String INSERT_FRAME_FOR_RESOURCE = "Insert frame for resource %1$s."; 
    232          
    233         /** 
    234          * Constant created for applying template for resource by name. 
    235          * Constant created to be a parameter of a message of an {@link AutoAction}.  
    236          * Used for skinning. 
    237          */ 
    238         public static final String APPLY_TEMPLATE_FOR_RESOURCE = "Apply template for resource %1$s.";  
    239  
    240         private static <D> ResourceRefR4 getNewResourceRef( 
    241                         final ResourceImportInfo<D> importInfo, 
    242                         final ResourceImportManager<D> importManager, 
    243                         BookH book) { 
    244                 assert importInfo != null : "Resource data can not be null!"; 
    245  
    246                 if (importInfo.isModelLinked() 
    247                                 && importManager instanceof SophieFormatImportManager) { 
    248                         File soureFile = new File(importInfo.getImportOrigin()); 
    249                         assert soureFile.exists() : "The import origin is not correctly set"; 
    250                         if (importInfo.getModelImportType() == ResourceImportType.COPY_AND_LINK) { 
    251                                 soureFile = ResourceFilesUtil.storeFile(book, soureFile); 
    252                                 assert soureFile.exists() : "Can not copy and link a specified resource."; 
    253                         } 
    254  
    255                         return ResourceRefR4.make(soureFile); 
    256                 } 
    257  
    258                 return importManager.generateChildRef();  
    259         } 
    260  
    261         /** 
    262          * Inserts a resource with a frame to Sophie. 
    263          *  
    264          * @param <D> 
    265          *                      The data used to create the resource. 
    266          * @param provider 
    267          *                      The {@link ResourceImportProvider} of the resource to insert. 
    268          * @param book 
    269          *                      The book in which the resource will be inserted. 
    270          * @param parent 
    271          *                      The parent of the frame to be inserted. 
    272          * @param pos  
    273          *                      The position where the frame will be inserted. 
    274          * @return 
    275          *                      True if the resource is inserted. 
    276          */ 
    277         @SuppressWarnings("unchecked") 
    278         public static <D> boolean insertResourceInFrame( 
    279                         ResourceImportProvider provider, BookH book, ElementH parent, ImmPoint pos) { 
    280                 final ResourceImportManager<D> importManager =  
    281                         (ResourceImportManager<D>) provider.getImportManager(); 
    282  
    283                 // Prepare the data for the resource to create. 
    284                 final ResourceRefR4 parentRef = ResourceRefR4.getRelativeRef( 
    285                                 book.getRef(), parent.getRef()); 
    286  
    287                 // Import the resource. 
    288                 List<ResourceImportInfo<D>> resourceData =  
    289                         importManager.retrieveResourceInfo(provider, book); 
    290  
    291                 if (resourceData == null || resourceData.isEmpty()) { 
    292                         return false; 
    293                 } 
    294  
    295                 for (ResourceImportInfo<D> info : resourceData) { 
    296                         insert(info, importManager, book, parent, parentRef, 
    297                                         getNewResourceRef(info, importManager, book), 
    298                                         pos); 
    299                 } 
    300  
    301                 return true; 
    302         } 
    303  
    304         /** 
    305          * Inserts frame for existing resource. 
    306          *  
    307          * @param <D> 
    308          *                      The data type of the resource. 
    309          * @param provider 
    310          *                      The {@link ResourceImportProvider}. 
    311          * @param book 
    312          *                      The current book containing the resource. 
    313          * @param parent 
    314          *                      The parent element of the frame to insert. 
    315          * @param pos 
    316          *                      The position at which the frame will be inserted. 
    317          * @param access 
    318          *                      The access to the existing resource. 
    319          * @param linked  
    320          *                      The resource from the frame will be linked. 
    321          * @return 
    322          *                      True if the frame was inserted successfully. 
    323          */ 
    324         @SuppressWarnings("unchecked") 
    325         public static <D> boolean insertRefFrame(ResourceImportProvider provider, 
    326                         BookH book, ElementH parent, ImmPoint pos,  
    327                         ResourceAccess access, boolean linked) { 
    328                 final ResourceImportManager<D> importManager =  
    329                         (ResourceImportManager<D>) provider.getImportManager(); 
    330  
    331                 final ResourceRefR4 parentRef = ResourceRefR4.getRelativeRef( 
    332                                 book.getRef(), parent.getRef()); 
    333  
    334                 assert access != null : "The access can not be null."; 
    335  
    336                 ResourceRefR4 resourceRef = (linked) ? ResourceRefR4.makeChild( 
    337                                 access.getRef().getName()) : importManager.generateChildRef(); 
    338  
    339                                 D data = importManager.getResourceData(access); 
    340  
    341                                 if (data == null) { 
    342                                         return false; 
    343                                 } 
    344  
    345                                 ResourceImportType importType = linked ? ResourceImportType.LINK : ResourceImportType.EMBED; 
    346                                 ResourceImportInfo<D> importInfo =  
    347                                         new ResourceImportInfo<D>(data, ResourceR4.KEY_TITLE.get(access), 
    348                                                         ResourceRefR4.NONE_REF.toUri(), importType); 
    349  
    350                                 insert(importInfo, importManager, book, parent, 
    351                                                 parentRef, resourceRef, pos); 
    352  
    353                                 return true; 
    354         } 
    355  
    356         /** 
    357          * Inserts a frame for dropped resource from outside Sophie 2.0. 
    358          *  
    359          * @param <D> 
    360          *                      The data type of the resource. 
    361          * @param provider 
    362          *                      The {@link ResourceImportProvider}. 
    363          * @param book 
    364          *                      The current book containing the resource. 
    365          * @param parent 
    366          *                      The parent element of the frame to insert. 
    367          * @param pos 
    368          *                      The position at which the frame will be inserted. 
    369          * @param transferable 
    370          *                      The {@link DndTransferable} whit which help the resource 
    371          *                      data can be retrieved. 
    372          * @return 
    373          *                      True if the frame was inserted successfully. 
    374          */ 
    375         @SuppressWarnings("unchecked") 
    376         public static <D> boolean dropResource(ResourceImportProvider provider, 
    377                         BookH book, ElementH parent, ImmPoint pos,  
    378                         DndTransferable transferable) { 
    379  
    380                 assert transferable != null : "The transferable can not be null."; 
    381  
    382                 final ResourceImportManager<D> importManager =  
    383                         (ResourceImportManager<D>) provider.getImportManager(); 
    384  
    385                 D data = importManager.getResourceData(transferable); 
    386  
    387                 String name = ResourceUtil.getNextTitle(parent.getRef(), getDefaultTitle(importManager)); 
    388  
    389                 return dropResource(provider, book, parent, pos, importManager, data, name); 
    390         } 
    391  
    392         /** 
    393          * Gets the default title prefix for resources imported by the given manager. 
    394          * You may want to use it together with {@link ResourceUtil#getNextTitle(ResourceRefR4, String)}. 
    395          *  
    396          * @param importManager 
    397          *              ResourceImportManager for which to return the default title. 
    398          * @return 
    399          *              The default title prefix for resources imported by the given manager. 
    400          */ 
    401         public static String getDefaultTitle(ResourceImportManager<?> importManager) { 
    402                 String resourceKind = importManager.getResourceKind(); 
    403                 Class<ResourceR4> resourceClass = ResourceR4.getClassByKind(resourceKind); 
    404                 String result = ResourceR4.DEFAULT_TITLE; 
    405  
    406                 try { 
    407                         result = (String) resourceClass.getField("DEFAULT_TITLE").get(null); 
    408                 } catch (Exception e) { 
    409                         // do nothing, just return a default value 
    410                 }  
    411  
    412                 return result; 
    413         } 
    414  
    415         /** 
    416          * Inserts a frame for a dropped file. 
    417          *  
    418          * @param <D> 
    419          *              The data type of the resource. 
    420          * @param provider 
    421          *              The {@link ResourceImportProvider}. 
    422          * @param book 
    423          *              The current book containing the resource. 
    424          * @param parent 
    425          *              The parent element of the frame to insert. 
    426          * @param pos 
    427          *              The position where the frame will be inserted. 
    428          * @param file 
    429          *              The file that should be inserted. 
    430          * @return 
    431          *              True if the frame was inserted successfully. 
    432          */ 
    433         @SuppressWarnings("unchecked") 
    434         public static <D> boolean dropFile(ResourceImportProvider provider, 
    435                         BookH book, ElementH parent, ImmPoint pos, File file) { 
    436  
    437                 final ResourceImportManager<D> importManager =  
    438                         (ResourceImportManager<D>) provider.getImportManager(); 
    439  
    440                 D data = importManager.getResourceData(file, book); 
    441  
    442                 return dropResource(provider, book, parent, pos, importManager, data, file.getName()); 
    443         } 
    444  
    445         private static <D> boolean dropResource(ResourceImportProvider provider, 
    446                         BookH book, ElementH parent, ImmPoint pos,  
    447                         ResourceImportManager<D> importManager, D data, 
    448                         String name) { 
    449  
    450                 if (data == null) { 
    451                         return false; 
    452                 } 
    453  
    454                 final ResourceRefR4 parentRef = ResourceRefR4.getRelativeRef( 
    455                                 book.getRef(), parent.getRef()); 
    456  
    457                 ResourceRefR4 resourceRef = importManager.generateChildRef(); 
    458  
    459                 ResourceImportInfo<D> importInfo =  
    460                         new ResourceImportInfo<D>(data, name); 
    461  
    462                 insert(importInfo, importManager, book, parent, 
    463                                 parentRef, resourceRef, pos); 
    464  
    465                 return true; 
    466         } 
    467  
    468         /** 
    469          * Shows user information for files that was not imported because 
    470          * they are invalid. 
    471          *  
    472          * @param invalidFiles 
    473          *                      The invalid files to show message for. 
    474          */ 
    475         public static void showInvalidInfo(List<File> invalidFiles) { 
    476                 if (!invalidFiles.isEmpty()) { 
    477                         StringBuffer badFiles = new StringBuffer(); 
    478  
    479                         for (File file : invalidFiles) { 
    480                                 badFiles.append(file.getName() + ", "); 
    481                         } 
    482                         //TODO: Skin this message --pap@2010-03-16 
    483                         MessageDialogInput errorInput = new MessageDialogInput(null, 
    484                                         "Some of the files specified were not valid : " + 
    485                                         badFiles.replace(badFiles.length() - 2, 
    486                                                         badFiles.length() - 1, "."), 
    487                                                         "Invalid Files", MessageType.ERROR); 
    488                         DialogManager.get().showDialog(errorInput); 
    489                 }  
    490         } 
    491  
    492         /** 
    493          * Extracts a zip file in the temporary directory and 
    494          * retrieves the files from it. 
    495          *  
    496          * @param zipped 
    497          *                      The zip file to be imported. 
    498          * @return  
    499          *                      List of the files in the zip. 
    500          */ 
    501         public static List<File> extractZipFile(File zipped) { 
    502                 List<File> fileList = new LinkedList<File>(); 
    503  
    504                 ZipFile zipFile; 
    505                 OutputStream out = null; 
    506                 InputStream is = null; 
    507  
    508                 try { 
    509                         zipFile = new ZipFile(zipped); 
    510                 } catch (Exception e) { 
    511                         DialogUtils.showErrorDialog(null, "Invalid zip file: "  
    512                                         + zipped, "Unzipping error"); 
    513                         return null; 
    514                 } 
    515                 Enumeration<?> entries = zipFile.entries(); 
    516  
    517                 String tempDir = System.getProperty("java.io.tmpdir"); 
    518  
    519                 while (entries.hasMoreElements()) { 
    520                         ZipEntry entry = (ZipEntry) entries.nextElement(); 
    521                         if (entry.isDirectory()) { 
    522                                 String fileName = tempDir + entry.getName(); 
    523                                 File dir = new File(fileName); 
    524                                 dir.mkdir(); 
    525                                 dir.deleteOnExit(); 
    526                                 continue; 
    527                         } 
    528  
    529                         try { 
    530                                 is = new BufferedInputStream(zipFile.getInputStream(entry)); 
    531                         } catch (IOException e) { 
    532                                 DialogUtils.showErrorDialog(null, "Error while extracting " 
    533                                                 + zipped + "!", "Unzipping error"); 
    534                                 return null; 
    535                         } 
    536  
    537                         int count; 
    538                         byte data[] = new byte[1024]; 
    539  
    540                         String fileName = tempDir + entry.getName(); 
    541  
    542                         File resFile = new File(fileName); 
    543                         resFile.deleteOnExit(); 
    544  
    545                         try{ 
    546                                 resFile.createNewFile(); 
    547                                 FileOutputStream fos = new FileOutputStream(resFile); 
    548                                 out = new BufferedOutputStream(fos, 1024); 
    549                                 while ((count = is.read(data, 0, 1024)) != -1) { 
    550                                         out.write(data, 0, count); 
    551                                 } 
    552  
    553                                 out.close(); 
    554                                 is.close(); 
    555                         } catch (IOException e) { 
    556                                 SophieLog.debug("Error while extracting : ", e); 
    557                                 DialogUtils.showErrorDialog(null, "Error while extracting " 
    558                                                 + zipped + " !", "Unzipping error"); 
    559                                 return null; 
    560                         } 
    561  
    562                         fileList.add(resFile); 
    563                 } 
    564  
    565                 if (fileList.size() == 0) { 
    566                         SophieLog.error("Zip file, passed for opening, is empty."); 
    567                         return null; 
    568                 } 
    569  
    570                 return fileList; 
    571         } 
    572  
    573  
    574 } 
     1package org.sophie2.main.func.resources.imports; 
     2 
     3import java.io.BufferedInputStream; 
     4import java.io.BufferedOutputStream; 
     5import java.io.File; 
     6import java.io.FileOutputStream; 
     7import java.io.IOException; 
     8import java.io.InputStream; 
     9import java.io.OutputStream; 
     10import java.util.Enumeration; 
     11import java.util.LinkedList; 
     12import java.util.List; 
     13import java.util.zip.ZipEntry; 
     14import java.util.zip.ZipFile; 
     15 
     16import org.sophie2.base.commons.util.ImmList; 
     17import org.sophie2.base.commons.util.NaiveImmList; 
     18import org.sophie2.base.commons.util.position.ImmPoint; 
     19import org.sophie2.base.commons.util.position.ImmSize; 
     20import org.sophie2.base.dialogs.DialogManager; 
     21import org.sophie2.base.dnd.DndTransferable; 
     22import org.sophie2.base.model.book.BookH; 
     23import org.sophie2.base.model.book.ElementH; 
     24import org.sophie2.base.model.book.FrameH; 
     25import org.sophie2.base.model.book.frame.FrameR4; 
     26import org.sophie2.base.model.book.interfaces.CompositeElement; 
     27import org.sophie2.base.model.book.resource.ResourceFilesUtil; 
     28import org.sophie2.base.model.book.timelines.ActivationChannel; 
     29import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     30import org.sophie2.base.model.resources.r4.ResourceUtil; 
     31import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
     32import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     33import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 
     34import org.sophie2.base.model.resources.r4.model.ResourceModel; 
     35import org.sophie2.base.model.resources.r4.resources.ResourceH; 
     36import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
     37import org.sophie2.base.skins.Message; 
     38import org.sophie2.core.logging.SophieLog; 
     39import org.sophie2.main.dialogs.input.DialogUtils; 
     40import org.sophie2.main.dialogs.input.MessageDialogInput; 
     41import org.sophie2.main.dialogs.input.MessageDialogInput.MessageType; 
     42import org.sophie2.main.dialogs.input.file.FileDialogInput; 
     43import org.sophie2.main.func.resources.actions.ApplyTemplateAction; 
     44import org.sophie2.main.func.resources.actions.ImportResourceAction; 
     45import org.sophie2.main.func.resources.actions.InsertFrameAction; 
     46import org.sophie2.main.func.resources.imports.bindata.ResourceImportType; 
     47 
     48/** 
     49 * Used to import different resources that are registered 
     50 * to be import-able.  
     51 *  
     52 * @author meddle 
     53 */ 
     54public final class ResourceImportUtil { 
     55 
     56        /** 
     57         * The provider used to open resources in Sophie Format. 
     58         * It is not registered as an extension and is used for 
     59         * handling import of any resource that is in Sophie 2.0 format.  
     60         */ 
     61        public static final ResourceImportProvider SOPHIE_FORMAT_PROVIDER =  
     62                new SimpleResourceImportProvider(new SophieFormatImportManager(), FileDialogInput.BOOK_FILTER); 
     63 
     64        /** 
     65         * Imports a resource in the passed book, without inserting a frame 
     66         * for it.  
     67         *  
     68         * @param <D> 
     69         *                      The data used to create the resource. 
     70         * @param provider 
     71         *                      The {@link ResourceImportProvider} of the resource to insert. 
     72         * @param book 
     73         *                      The book in which the resource will be inserted. 
     74         * @param resFile 
     75         *                      The file from which the resource is imported.  
     76         * @return 
     77         *                      True if the resource is inserted. 
     78         */ 
     79        @SuppressWarnings("unchecked") 
     80        public static <D> ResourceRefR4 importResource(ResourceImportProvider provider, 
     81                        ResourceH book, File resFile) { 
     82                final ResourceImportManager<D> importManager =  
     83                        (ResourceImportManager<D>) provider.getImportManager(); 
     84 
     85                D data =  
     86                        importManager.getResourceData(resFile, book); 
     87 
     88                if (data == null) { 
     89                        return null; 
     90                } 
     91 
     92                final ResourceRefR4 resourceRef = importManager.generateChildRef(); 
     93 
     94                final ResourceImportInfo<D> importInfo =  
     95                        new ResourceImportInfo<D>(data, resFile.getName(), resFile.toURI(), 
     96                                        ResourceImportType.EMBED); 
     97 
     98                Message description = Message.create(IMPORT_RES, importInfo.getName()); 
     99                ImportResourceAction<D> action = new ImportResourceAction<D>( 
     100                                description, true, importInfo, resourceRef, importManager); 
     101                action.register(book.getAccess()); 
     102 
     103                return resourceRef; 
     104        }        
     105         
     106        /** 
     107         * Imports the Sophie2 resource carried by the given transferable in the current book. 
     108         *  
     109         * @param book 
     110         *              The book in which the resource will be inserted. 
     111         * @param transferable 
     112         *              The transferable carrying the resource to import. 
     113         * @param significant 
     114         *              Whether the AutoAction should be registered as significant. 
     115         * @return 
     116         *              An absolute reference to the imported resource or null if no resource was imported. 
     117         */ 
     118        @SuppressWarnings("unchecked") 
     119        public static ResourceRefR4 importResource(BookH book, DndTransferable transferable, 
     120                        boolean significant) { 
     121                 
     122                final ResourceImportManager<?> importManager =  
     123                        ResourceImportUtil.SOPHIE_FORMAT_PROVIDER.getImportManager(); 
     124                ResourceModel data = (ResourceModel) importManager.getResourceData(transferable); 
     125                if (data == null) { 
     126                        return null; 
     127                } 
     128                 
     129                String title = data.getRaw(ResourceR4.KEY_TITLE); 
     130                final ResourceImportInfo importInfo = new ResourceImportInfo(data, title); 
     131                final ResourceRefR4 childRef = importManager.generateChildRef(); 
     132                 
     133                Message description = Message.create(IMPORT_RES, importInfo.getName()); 
     134                AutoAction action = new ImportResourceAction( 
     135                                description, significant, importInfo, childRef, importManager); 
     136                action.register(book.getAccess()); 
     137                 
     138                return book.getRef().append(childRef); 
     139        } 
     140         
     141        /** 
     142         * Constant created for importing resources by resource name. 
     143         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     144         * Used for skinning. 
     145         */ 
     146        public final static String IMPORT_RES = "Import resource %1$s."; 
     147 
     148        private static <D> void insert(final ResourceImportInfo<D> importInfo, 
     149                        final ResourceImportManager<D> importManager, BookH book, 
     150                        ElementH parent, final ResourceRefR4 parentRef, 
     151                        final ResourceRefR4 resourceRef, 
     152                        final ImmPoint pos) { 
     153 
     154                assert importInfo != null : "Resource data can not be null!"; 
     155 
     156                final ResourceRefR4 frameRef =  
     157                        ResourceRefR4.generateRandomSub(FrameH.NAME_PREFIX); 
     158 
     159                // Prepare data for the frame to insert. 
     160                final ImmSize frameSize =  
     161                        importManager.computeFrameSize(importInfo.getData());    
     162 
     163                final String frameTitle =  
     164                        importInfo.getName() + " " + FrameR4.DEFAULT_TITLE; 
     165 
     166                final ImmList<ActivationChannel> elements =  
     167                        CompositeElement.KEY_SUB_ELEMENTS.get(parent.getAccess()); 
     168                ResourceRefR4 defaultTemplate = book.getDefaultFrameTemplate(); 
     169                final boolean isDefaultTemplate = ! defaultTemplate.equals(ResourceRefR4.NONE_REF); 
     170                final boolean linked = importInfo.isModelLinked();  
     171 
     172 
     173                Message description = Message.create(INSERT_FRAME_FOR_RESOURCE, importInfo.getName()); 
     174                AutoAction action = new InsertFrameAction<D>(description, true, importInfo,  
     175                                frameRef, pos, frameSize, elements, parentRef, importManager, linked, 
     176                                resourceRef, frameTitle); 
     177                action.register(book.getAccess()); 
     178                 
     179                if (isDefaultTemplate) { 
     180                        ResourceRefR4 absoluteDefRef = book.getRef().getAbsolute(defaultTemplate); 
     181                        ResourceRefR4 absoluteFrameRef = parent.getRef().getAbsolute(frameRef); 
     182                         
     183                        assert absoluteDefRef.isAbsolute(); 
     184                        final ResourceRefR4 templateRef = ResourceRefR4.getRelativeRef(absoluteFrameRef, 
     185                                        absoluteDefRef); 
     186 
     187                        ResourceAccess templateAccess = book.getAccess().open(absoluteDefRef , null); 
     188 
     189                        ResourceAccess frameAccess = parent.getAccess().open(frameRef, null); 
     190                        final String kind = templateAccess.getRaw(ResourceR4.KEY_KIND); 
     191 
     192                        FrameH templateH = ResourceH.getHelper(templateAccess, FrameH.class); 
     193                        final NaiveImmList<TemplatedKey<?>> immKeys = templateH.getApplicableTemplatedKeys(); 
     194 
     195                        description = Message.create(APPLY_TEMPLATE_FOR_RESOURCE, importInfo.getName()); 
     196                        action =  
     197                                new ApplyTemplateAction(description, false, immKeys, templateRef, kind); 
     198                        action.register(frameAccess); 
     199                } 
     200        } 
     201         
     202        /** 
     203         * Constant created for inserting frame for resource by name. 
     204         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     205         * Used for skinning. 
     206         */ 
     207        public static final String INSERT_FRAME_FOR_RESOURCE = "Insert frame for resource %1$s."; 
     208         
     209        /** 
     210         * Constant created for applying template for resource by name. 
     211         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     212         * Used for skinning. 
     213         */ 
     214        public static final String APPLY_TEMPLATE_FOR_RESOURCE = "Apply template for resource %1$s.";  
     215 
     216        private static <D> ResourceRefR4 getNewResourceRef( 
     217                        final ResourceImportInfo<D> importInfo, 
     218                        final ResourceImportManager<D> importManager, 
     219                        BookH book) { 
     220                assert importInfo != null : "Resource data can not be null!"; 
     221 
     222                if (importInfo.isModelLinked() 
     223                                && importManager instanceof SophieFormatImportManager) { 
     224                        File soureFile = new File(importInfo.getImportOrigin()); 
     225                        assert soureFile.exists() : "The import origin is not correctly set"; 
     226                        if (importInfo.getModelImportType() == ResourceImportType.COPY_AND_LINK) { 
     227                                soureFile = ResourceFilesUtil.storeFile(book, soureFile); 
     228                                assert soureFile.exists() : "Can not copy and link a specified resource."; 
     229                        } 
     230 
     231                        return ResourceRefR4.make(soureFile); 
     232                } 
     233 
     234                return importManager.generateChildRef();  
     235        } 
     236 
     237        /** 
     238         * Inserts a resource with a frame to Sophie. 
     239         *  
     240         * @param <D> 
     241         *                      The data used to create the resource. 
     242         * @param provider 
     243         *                      The {@link ResourceImportProvider} of the resource to insert. 
     244         * @param book 
     245         *                      The book in which the resource will be inserted. 
     246         * @param parent 
     247         *                      The parent of the frame to be inserted. 
     248         * @param pos  
     249         *                      The position where the frame will be inserted. 
     250         * @return 
     251         *                      True if the resource is inserted. 
     252         */ 
     253        @SuppressWarnings("unchecked") 
     254        public static <D> boolean insertResourceInFrame( 
     255                        ResourceImportProvider provider, BookH book, ElementH parent, ImmPoint pos) { 
     256                final ResourceImportManager<D> importManager =  
     257                        (ResourceImportManager<D>) provider.getImportManager(); 
     258 
     259                // Prepare the data for the resource to create. 
     260                final ResourceRefR4 parentRef = ResourceRefR4.getRelativeRef( 
     261                                book.getRef(), parent.getRef()); 
     262 
     263                // Import the resource. 
     264                List<ResourceImportInfo<D>> resourceData =  
     265                        importManager.retrieveResourceInfo(provider, book); 
     266 
     267                if (resourceData == null || resourceData.isEmpty()) { 
     268                        return false; 
     269                } 
     270 
     271                for (ResourceImportInfo<D> info : resourceData) { 
     272                        insert(info, importManager, book, parent, parentRef, 
     273                                        getNewResourceRef(info, importManager, book), 
     274                                        pos); 
     275                } 
     276 
     277                return true; 
     278        } 
     279 
     280        /** 
     281         * Inserts frame for existing resource. 
     282         *  
     283         * @param <D> 
     284         *                      The data type of the resource. 
     285         * @param provider 
     286         *                      The {@link ResourceImportProvider}. 
     287         * @param book 
     288         *                      The current book containing the resource. 
     289         * @param parent 
     290         *                      The parent element of the frame to insert. 
     291         * @param pos 
     292         *                      The position at which the frame will be inserted. 
     293         * @param access 
     294         *                      The access to the existing resource. 
     295         * @param linked  
     296         *                      The resource from the frame will be linked. 
     297         * @return 
     298         *                      True if the frame was inserted successfully. 
     299         */ 
     300        @SuppressWarnings("unchecked") 
     301        public static <D> boolean insertRefFrame(ResourceImportProvider provider, 
     302                        BookH book, ElementH parent, ImmPoint pos,  
     303                        ResourceAccess access, boolean linked) { 
     304                final ResourceImportManager<D> importManager =  
     305                        (ResourceImportManager<D>) provider.getImportManager(); 
     306 
     307                final ResourceRefR4 parentRef = ResourceRefR4.getRelativeRef( 
     308                                book.getRef(), parent.getRef()); 
     309 
     310                assert access != null : "The access can not be null."; 
     311 
     312                ResourceRefR4 resourceRef = (linked) ? ResourceRefR4.makeChild( 
     313                                access.getRef().getName()) : importManager.generateChildRef(); 
     314 
     315                                D data = importManager.getResourceData(access); 
     316 
     317                                if (data == null) { 
     318                                        return false; 
     319                                } 
     320 
     321                                ResourceImportType importType = linked ? ResourceImportType.LINK : ResourceImportType.EMBED; 
     322                                ResourceImportInfo<D> importInfo =  
     323                                        new ResourceImportInfo<D>(data, ResourceR4.KEY_TITLE.get(access), 
     324                                                        ResourceRefR4.NONE_REF.toUri(), importType); 
     325 
     326                                insert(importInfo, importManager, book, parent, 
     327                                                parentRef, resourceRef, pos); 
     328 
     329                                return true; 
     330        } 
     331 
     332        /** 
     333         * Inserts a frame for dropped resource from outside Sophie 2.0. 
     334         *  
     335         * @param <D> 
     336         *                      The data type of the resource. 
     337         * @param provider 
     338         *                      The {@link ResourceImportProvider}. 
     339         * @param book 
     340         *                      The current book containing the resource. 
     341         * @param parent 
     342         *                      The parent element of the frame to insert. 
     343         * @param pos 
     344         *                      The position at which the frame will be inserted. 
     345         * @param transferable 
     346         *                      The {@link DndTransferable} whit which help the resource 
     347         *                      data can be retrieved. 
     348         * @return 
     349         *                      True if the frame was inserted successfully. 
     350         */ 
     351        @SuppressWarnings("unchecked") 
     352        public static <D> boolean dropResource(ResourceImportProvider provider, 
     353                        BookH book, ElementH parent, ImmPoint pos,  
     354                        DndTransferable transferable) { 
     355 
     356                assert transferable != null : "The transferable can not be null."; 
     357 
     358                final ResourceImportManager<D> importManager =  
     359                        (ResourceImportManager<D>) provider.getImportManager(); 
     360 
     361                D data = importManager.getResourceData(transferable); 
     362 
     363                String name = ResourceUtil.getNextTitle(parent.getRef(), getDefaultTitle(importManager)); 
     364 
     365                return dropResource(provider, book, parent, pos, importManager, data, name); 
     366        } 
     367 
     368        /** 
     369         * Gets the default title prefix for resources imported by the given manager. 
     370         * You may want to use it together with {@link ResourceUtil#getNextTitle(ResourceRefR4, String)}. 
     371         *  
     372         * @param importManager 
     373         *              ResourceImportManager for which to return the default title. 
     374         * @return 
     375         *              The default title prefix for resources imported by the given manager. 
     376         */ 
     377        public static String getDefaultTitle(ResourceImportManager<?> importManager) { 
     378                String resourceKind = importManager.getResourceKind(); 
     379                Class<ResourceR4> resourceClass = ResourceR4.getClassByKind(resourceKind); 
     380                String result = ResourceR4.DEFAULT_TITLE; 
     381 
     382                try { 
     383                        result = (String) resourceClass.getField("DEFAULT_TITLE").get(null); 
     384                } catch (Exception e) { 
     385                        // do nothing, just return a default value 
     386                }  
     387 
     388                return result; 
     389        } 
     390 
     391        /** 
     392         * Inserts a frame for a dropped file. 
     393         *  
     394         * @param <D> 
     395         *              The data type of the resource. 
     396         * @param provider 
     397         *              The {@link ResourceImportProvider}. 
     398         * @param book 
     399         *              The current book containing the resource. 
     400         * @param parent 
     401         *              The parent element of the frame to insert. 
     402         * @param pos 
     403         *              The position where the frame will be inserted. 
     404         * @param file 
     405         *              The file that should be inserted. 
     406         * @return 
     407         *              True if the frame was inserted successfully. 
     408         */ 
     409        @SuppressWarnings("unchecked") 
     410        public static <D> boolean dropFile(ResourceImportProvider provider, 
     411                        BookH book, ElementH parent, ImmPoint pos, File file) { 
     412 
     413                final ResourceImportManager<D> importManager =  
     414                        (ResourceImportManager<D>) provider.getImportManager(); 
     415 
     416                D data = importManager.getResourceData(file, book); 
     417 
     418                return dropResource(provider, book, parent, pos, importManager, data, file.getName()); 
     419        } 
     420 
     421        private static <D> boolean dropResource(ResourceImportProvider provider, 
     422                        BookH book, ElementH parent, ImmPoint pos,  
     423                        ResourceImportManager<D> importManager, D data, 
     424                        String name) { 
     425 
     426                if (data == null) { 
     427                        return false; 
     428                } 
     429 
     430                final ResourceRefR4 parentRef = ResourceRefR4.getRelativeRef( 
     431                                book.getRef(), parent.getRef()); 
     432 
     433                ResourceRefR4 resourceRef = importManager.generateChildRef(); 
     434 
     435                ResourceImportInfo<D> importInfo =  
     436                        new ResourceImportInfo<D>(data, name); 
     437 
     438                insert(importInfo, importManager, book, parent, 
     439                                parentRef, resourceRef, pos); 
     440 
     441                return true; 
     442        } 
     443 
     444        /** 
     445         * Shows user information for files that was not imported because 
     446         * they are invalid. 
     447         *  
     448         * @param invalidFiles 
     449         *                      The invalid files to show message for. 
     450         */ 
     451        public static void showInvalidInfo(List<File> invalidFiles) { 
     452                if (!invalidFiles.isEmpty()) { 
     453                        StringBuffer badFiles = new StringBuffer(); 
     454 
     455                        for (File file : invalidFiles) { 
     456                                badFiles.append(file.getName() + ", "); 
     457                        } 
     458                        //TODO: Skin this message --pap@2010-03-16 
     459                        MessageDialogInput errorInput = new MessageDialogInput(null, 
     460                                        "Some of the files specified were not valid : " + 
     461                                        badFiles.replace(badFiles.length() - 2, 
     462                                                        badFiles.length() - 1, "."), 
     463                                                        "Invalid Files", MessageType.ERROR); 
     464                        DialogManager.get().showDialog(errorInput); 
     465                }  
     466        } 
     467 
     468        /** 
     469         * Extracts a zip file in the temporary directory and 
     470         * retrieves the files from it. 
     471         *  
     472         * @param zipped 
     473         *                      The zip file to be imported. 
     474         * @return  
     475         *                      List of the files in the zip. 
     476         */ 
     477        public static List<File> extractZipFile(File zipped) { 
     478                List<File> fileList = new LinkedList<File>(); 
     479 
     480                ZipFile zipFile; 
     481                OutputStream out = null; 
     482                InputStream is = null; 
     483 
     484                try { 
     485                        zipFile = new ZipFile(zipped); 
     486                } catch (Exception e) { 
     487                        DialogUtils.showErrorDialog(null, "Invalid zip file: "  
     488                                        + zipped, "Unzipping error"); 
     489                        return null; 
     490                } 
     491                Enumeration<?> entries = zipFile.entries(); 
     492 
     493                String tempDir = System.getProperty("java.io.tmpdir"); 
     494 
     495                while (entries.hasMoreElements()) { 
     496                        ZipEntry entry = (ZipEntry) entries.nextElement(); 
     497                        if (entry.isDirectory()) { 
     498                                String fileName = tempDir + entry.getName(); 
     499                                File dir = new File(fileName); 
     500                                dir.mkdir(); 
     501                                dir.deleteOnExit(); 
     502                                continue; 
     503                        } 
     504 
     505                        try { 
     506                                is = new BufferedInputStream(zipFile.getInputStream(entry)); 
     507                        } catch (IOException e) { 
     508                                DialogUtils.showErrorDialog(null, "Error while extracting " 
     509                                                + zipped + "!", "Unzipping error"); 
     510                                return null; 
     511                        } 
     512 
     513                        int count; 
     514                        byte data[] = new byte[1024]; 
     515 
     516                        String fileName = tempDir + ResourceFilesUtil.FILE_SEPARATOR + entry.getName(); 
     517 
     518                        File resFile = new File(fileName); 
     519                        resFile.deleteOnExit(); 
     520 
     521                        try { 
     522                                new File(resFile.getParent()).mkdirs(); 
     523                                resFile.createNewFile(); 
     524                                FileOutputStream fos = new FileOutputStream(resFile); 
     525                                out = new BufferedOutputStream(fos, 1024); 
     526                                while ((count = is.read(data, 0, 1024)) != -1) { 
     527                                        out.write(data, 0, count); 
     528                                } 
     529 
     530                                out.close(); 
     531                                is.close(); 
     532                        } catch (IOException e) { 
     533                                SophieLog.debug("Error while extracting : ", e); 
     534                                DialogUtils.showErrorDialog(null, "Error while extracting " 
     535                                                + zipped + " !", "Unzipping error"); 
     536                                return null; 
     537                        } 
     538 
     539                        fileList.add(resFile); 
     540                } 
     541 
     542                if (fileList.size() == 0) { 
     543                        SophieLog.error("Zip file, passed for opening, is empty."); 
     544                        return null; 
     545                } 
     546 
     547                return fileList; 
     548        } 
     549 
     550 
     551} 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/logic/ChangeFrameMainResourceHandler.java

     
    33import org.sophie2.base.dnd.DndTransferable; 
    44import org.sophie2.base.dnd.DropHandler; 
    55import org.sophie2.base.model.book.BookH; 
    6 import org.sophie2.base.model.book.interfaces.ResourceFrame; 
    76import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    87import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    98import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     
    1514import org.sophie2.main.app.commons.element.ElementDropHandler; 
    1615import org.sophie2.main.app.commons.frame.FrameView; 
    1716import org.sophie2.main.dnd.dnddata.ResourceRefData; 
     17import org.sophie2.main.func.resources.actions.SetFrameResourceAction; 
    1818import org.sophie2.main.func.resources.imports.ResourceImportProvider; 
    1919import org.sophie2.main.func.resources.imports.ResourceImportUtil; 
    2020import org.sophie2.main.func.resources.imports.SimpleResourceImportProvider; 
     
    8888                LogicR3.fire(getView(), bdw, null, null, BookView.EventIds.DELETING_ELEMENT, 
    8989                                ResourceDeleteLogic.findElementView(bookToFrameRef, getView().getBookView())); 
    9090                 
    91                 new AutoAction(Message.create(MAIN_RESOURCE_OF_FRAME), true) { 
    92                          
    93                         @Override 
    94                         public void performAuto() { 
    95                                 getChanger().setRaw(ResourceR4.KEY_KIND, newFrameKind); 
    96                                 getChanger().setRaw(ResourceFrame.KEY_MAIN_RESOURCE, relRef); 
    97                         } 
    98                 }.register(frameAccess); 
     91                Message description = Message.create(MAIN_RESOURCE_OF_FRAME); 
     92                AutoAction action = new SetFrameResourceAction(description, true, relRef, newFrameKind); 
     93                action.register(frameAccess); 
    9994        } 
    10095} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/imports/ResourceImportManagerTest.java

     
    1 package org.sophie2.main.func.resources.imports; 
    2  
    3 import java.io.File; 
    4 import java.util.Arrays; 
    5 import java.util.List; 
    6  
    7 import org.junit.Before; 
    8 import org.junit.Test; 
    9 import org.sophie2.base.commons.BaseCommonsModule; 
    10 import org.sophie2.base.commons.structures.ImmTreeList; 
    11 import org.sophie2.base.commons.util.ImmList; 
    12 import org.sophie2.base.commons.util.position.ImmPoint; 
    13 import org.sophie2.base.dialogs.BaseDialogsModule; 
    14 import org.sophie2.base.dialogs.TestingDialogManager; 
    15 import org.sophie2.base.media.BaseMediaModule; 
    16 import org.sophie2.base.model.book.BaseModelBookModule; 
    17 import org.sophie2.base.model.book.FrameH; 
    18 import org.sophie2.base.model.book.frame.FrameR4; 
    19 import org.sophie2.base.model.book.interfaces.ResourceFrame; 
    20 import org.sophie2.base.model.book.resource.r4.BookR4; 
    21 import org.sophie2.base.model.book.timelines.ActivationChannel; 
    22 import org.sophie2.base.model.resources.r4.BaseModelResourcesR4Module; 
    23 import org.sophie2.base.model.resources.r4.ResourceRefList; 
    24 import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    25 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    26 import org.sophie2.base.model.resources.r4.changes.AutoAction; 
    27 import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 
    28 import org.sophie2.base.model.resources.r4.keys.ChildrenKey; 
    29 import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 
    30 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
    31 import org.sophie2.base.skins.BaseSkinsModule; 
    32 import org.sophie2.base.skins.Message; 
    33 import org.sophie2.base.visual.BaseVisualModule; 
    34 import org.sophie2.core.modularity.FileEntryManager; 
    35 import org.sophie2.core.modularity.SophieModule; 
    36 import org.sophie2.main.app.commons.MainAppModule; 
    37 import org.sophie2.main.app.commons.testing.AppTestBase; 
    38 import org.sophie2.main.dialogs.input.MessageDialogInput; 
    39 import org.sophie2.main.dialogs.input.file.FileContainer; 
    40 import org.sophie2.main.dialogs.input.file.FileDialogInput; 
    41 import org.sophie2.main.dialogs.input.file.FileFilterInfo; 
    42 import org.sophie2.main.func.file.FileFunctionalityModule; 
    43 import org.sophie2.main.func.resources.dummy.ColdTextImportManager; 
    44 import org.sophie2.main.func.resources.dummy.ColdTextModule; 
    45 import org.sophie2.main.func.resources.dummy.ColdTextResource; 
    46 import org.sophie2.main.func.resources.dummy.ColdTextResourceHelper; 
    47 import org.sophie2.main.media.natlib.MainMediaNatlibModule; 
    48  
    49 /** 
    50  * Test the common logic implemented in the {@link ResourceImportManager}. 
    51  *  
    52  * @author meddle 
    53  */ 
    54 public class ResourceImportManagerTest extends AppTestBase { 
    55          
    56         /** 
    57          * Constant created for inserting the frame. 
    58          * Constant created to be a parameter of a message of an {@link AutoAction}.  
    59          * Used for skinning. Used in the test. 
    60          */ 
    61         public static final String INSERT_THE_FRAME = "Insert the frame."; 
    62  
    63         /** 
    64          * Constant created for creating cold text. 
    65          * Constant created to be a parameter of a message of an {@link AutoAction}.  
    66          * Used for skinning. 
    67          */ 
    68         public static final String CREATING_COLD_TEXT = "Creating cold text"; 
    69  
    70         private ResourceImportProvider provider; 
    71          
    72         /** 
    73          * Files for testing. 
    74          */ 
    75         public static final String[] FILES_TO_TEST =  
    76                 new String[] {"text1.txt", "text2.txt", "pic1.jpg", "test.zip"}; 
    77          
    78         @SuppressWarnings("unchecked") 
    79         @Override 
    80         protected List<Class<? extends SophieModule>> fillDependencies() { 
    81                 return Arrays.asList(BaseModelResourcesR4Module.class, 
    82                                 BaseVisualModule.class, BaseMediaModule.class, 
    83                                 BaseCommonsModule.class, MainMediaNatlibModule.class, 
    84                                 BaseDialogsModule.class, BaseSkinsModule.class, 
    85                                 BaseModelBookModule.class, FileFunctionalityModule.class, 
    86                                 MainAppModule.class, 
    87                                 ColdTextModule.class); 
    88         } 
    89          
    90         @Override 
    91         @Before 
    92         protected void setUp() throws Exception { 
    93                 super.setUp(); 
    94                  
    95                 this.provider = new SimpleResourceImportProvider( 
    96                                 new ColdTextImportManager(),  
    97                                 new FileFilterInfo(ColdTextImportManager.FILE_FILTER)); 
    98         } 
    99          
    100         /** 
    101          * Tests if the {@link ResourceImportManager#generateChildRef()} 
    102          * is working correctly. 
    103          *  
    104          * @throws Exception 
    105          */ 
    106         @Test 
    107         public void testGenerateChildRef() throws Exception { 
    108                 ColdTextImportManager manager =  
    109                         (ColdTextImportManager) this.provider.getImportManager(); 
    110                  
    111                 ResourceRefR4 ref = manager.generateChildRef(); 
    112                  
    113                 assertNotNull(ref); 
    114                 assertTrue(ref.getLocation().contains(ColdTextResourceHelper.NAME_PREFIX)); 
    115         } 
    116          
    117         /** 
    118          * Tests the default retrieving of resource info. 
    119          *  
    120          * @throws Exception 
    121          */ 
    122         @Test 
    123         public void testRetrieveResourceInfo() throws Exception { 
    124                 ColdTextImportManager manager =  
    125                         (ColdTextImportManager) this.provider.getImportManager(); 
    126                  
    127                 File file1 = new File(FileEntryManager.get().getReadableFileEntry( 
    128                                 FILES_TO_TEST[0]).getFile()); 
    129                 File file2 = new File(FileEntryManager.get().getReadableFileEntry( 
    130                                 FILES_TO_TEST[0]).getFile()); 
    131                  
    132                 TestingDialogManager.get().expect(FileDialogInput.class,  
    133                                 new FileContainer(file1, file2)); 
    134                  
    135                 List<ResourceImportInfo<String>> infos =  
    136                         manager.retrieveResourceInfo(this.provider, null); 
    137                  
    138                 assertEquals(2, infos.size()); 
    139                  
    140                 ResourceImportInfo<String> info1 = infos.get(0); 
    141                 assertNotNull(info1); 
    142                 assertEquals(file1.getName(), info1.getName()); 
    143                 assertEquals(file1.toURI(), info1.getImportOrigin()); 
    144                 assertEquals(manager.getResourceData(file1, null), info1.getData()); 
    145                  
    146                 ResourceImportInfo<String> info2 = infos.get(1); 
    147                 assertNotNull(info2); 
    148                 assertEquals(file2.getName(), info2.getName()); 
    149                 assertEquals(file2.toURI(), info2.getImportOrigin()); 
    150                 assertEquals(manager.getResourceData(file2, null), info2.getData()); 
    151                  
    152                 // Test with file in other format: 
    153                 File file3 = new File(FileEntryManager.get().getReadableFileEntry( 
    154                                 FILES_TO_TEST[2]).getFile()); 
    155                  
    156                 TestingDialogManager.get().expect(FileDialogInput.class,  
    157                                 new FileContainer(file1, file3)); 
    158                  
    159                 TestingDialogManager.get().expect(MessageDialogInput.class,  
    160                                 null); 
    161                  
    162                 infos =  
    163                         manager.retrieveResourceInfo(this.provider, null); 
    164                 assertEquals(1, infos.size()); 
    165                  
    166                 info1 = infos.get(0); 
    167                 assertNotNull(info1); 
    168                 assertEquals(file1.getName(), info1.getName()); 
    169                 assertEquals(file1.toURI(), info1.getImportOrigin()); 
    170                 assertEquals(manager.getResourceData(file1, null), info1.getData()); 
    171         } 
    172          
    173         /** 
    174          * Tests the {@link ResourceImportManager}'s inserting of frames. 
    175          *  
    176          * @throws Exception 
    177          */ 
    178         @Test 
    179         public void testInsertFrame() throws Exception { 
    180                 ResourceAccess bookAccess = makeBookAccess(); 
    181                  
    182                 final ResourceRefR4 coldRef =  
    183                         ResourceRefR4.generateRandomSub(ColdTextResource.DEFAULT_TITLE); 
    184                 final String text = "Some text"; 
    185                  
    186                 new AutoAction(Message.create(CREATING_COLD_TEXT), true) { 
    187                         @Override 
    188                         public void performAuto() { 
    189                                 ColdTextResourceHelper.createColdText( 
    190                                                 getChanger(), coldRef, text); 
    191                         } 
    192                 }.register(bookAccess); 
    193                  
    194                 SubEntryNames children = ResourceR4.KEY_CHILDREN.get(bookAccess); 
    195                  
    196                 // With the page : 
    197                 assertEquals(2, children.size()); 
    198                  
    199                 final ColdTextImportManager manager =  
    200                         (ColdTextImportManager) this.provider.getImportManager(); 
    201                  
    202                 ResourceRefList pages = BookR4.KEY_PAGES.get(bookAccess); 
    203                 assertEquals(1, pages.size()); 
    204                  
    205                 final ResourceRefR4 parentRef = pages.get(0); 
    206                 final ResourceRefR4 frameRef =  
    207                         ResourceRefR4.generateRandomSub(FrameH.NAME_PREFIX); 
    208                 final ImmList<ActivationChannel> elements = ImmTreeList.empty(); 
    209                  
    210                 new AutoAction(Message.create(INSERT_THE_FRAME), true) { 
    211                         @Override 
    212                         public void performAuto() { 
    213                                 manager.insertFrame(getChanger().getSub(parentRef), 
    214                                                 parentRef, frameRef, coldRef, 
    215                                                 "Bau", elements, 
    216                                                 ImmPoint.ZERO, 
    217                                                 FrameR4.DEFAULT_FRAME_SIZE); 
    218                         } 
    219                          
    220                 }.register(bookAccess); 
    221                  
    222                 ChildrenKey pageChildrenKey =  
    223                         ResourceR4.KEY_CHILDREN.sub(parentRef).sub(ResourceR4.KEY_CHILDREN); 
    224                  
    225                 SubEntryNames frames = pageChildrenKey.get(bookAccess); 
    226                  
    227                 assertEquals(1, frames.size()); 
    228                  
    229                  TemplatedKey<ResourceRefR4> mainResKey =  
    230                          pageChildrenKey.sub(frameRef).sub(ResourceFrame.KEY_MAIN_RESOURCE); 
    231                  
    232                  ResourceRefR4 mainResRef = mainResKey.get(bookAccess); 
    233                   
    234                 ResourceRefR4 pageToFrameRef = parentRef.append(frameRef); 
    235                 ResourceRefR4 frameToContentRef = ResourceRefR4.getRelativeRef( 
    236                                 pageToFrameRef, coldRef); 
    237                 assertEquals(frameToContentRef, mainResRef); 
    238                  
    239         } 
    240          
    241 } 
     1package org.sophie2.main.func.resources.imports; 
     2 
     3import java.io.File; 
     4import java.util.Arrays; 
     5import java.util.List; 
     6 
     7import org.junit.Before; 
     8import org.junit.Test; 
     9import org.sophie2.base.bound.BoundModule; 
     10import org.sophie2.base.commons.BaseCommonsModule; 
     11import org.sophie2.base.commons.structures.ImmTreeList; 
     12import org.sophie2.base.commons.util.ImmList; 
     13import org.sophie2.base.config.BaseConfigModule; 
     14import org.sophie2.base.dialogs.BaseDialogsModule; 
     15import org.sophie2.base.dialogs.TestingDialogManager; 
     16import org.sophie2.base.media.BaseMediaModule; 
     17import org.sophie2.base.model.book.BaseModelBookModule; 
     18import org.sophie2.base.model.book.FrameH; 
     19import org.sophie2.base.model.book.interfaces.ResourceFrame; 
     20import org.sophie2.base.model.book.resource.r4.BookR4; 
     21import org.sophie2.base.model.book.timelines.ActivationChannel; 
     22import org.sophie2.base.model.resources.r4.BaseModelResourcesR4Module; 
     23import org.sophie2.base.model.resources.r4.ResourceRefList; 
     24import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     25import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
     26import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     27import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 
     28import org.sophie2.base.model.resources.r4.keys.ChildrenKey; 
     29import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 
     30import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
     31import org.sophie2.base.persistence.BasePersistenceModule; 
     32import org.sophie2.base.skins.BaseSkinsModule; 
     33import org.sophie2.base.skins.Message; 
     34import org.sophie2.base.visual.BaseVisualModule; 
     35import org.sophie2.core.modularity.FileEntryManager; 
     36import org.sophie2.core.modularity.SophieModule; 
     37import org.sophie2.main.app.commons.MainAppModule; 
     38import org.sophie2.main.app.commons.testing.AppTestBase; 
     39import org.sophie2.main.dialogs.input.MessageDialogInput; 
     40import org.sophie2.main.dialogs.input.file.FileContainer; 
     41import org.sophie2.main.dialogs.input.file.FileDialogInput; 
     42import org.sophie2.main.dialogs.input.file.FileFilterInfo; 
     43import org.sophie2.main.func.file.FileFunctionalityModule; 
     44import org.sophie2.main.func.resources.actions.CreateColdTextAction; 
     45import org.sophie2.main.func.resources.actions.InsertTextFrameAction; 
     46import org.sophie2.main.func.resources.dummy.ColdTextImportManager; 
     47import org.sophie2.main.func.resources.dummy.ColdTextModule; 
     48import org.sophie2.main.func.resources.dummy.ColdTextResource; 
     49import org.sophie2.main.func.resources.dummy.ColdTextResourceHelper; 
     50import org.sophie2.main.media.natlib.MainMediaNatlibModule; 
     51 
     52/** 
     53 * Test the common logic implemented in the {@link ResourceImportManager}. 
     54 *  
     55 * @author meddle 
     56 */ 
     57public class ResourceImportManagerTest extends AppTestBase { 
     58         
     59        /** 
     60         * Constant created for inserting the frame. 
     61         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     62         * Used for skinning. Used in the test. 
     63         */ 
     64        public static final String INSERT_THE_FRAME = "Insert the frame."; 
     65 
     66        /** 
     67         * Constant created for creating cold text. 
     68         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     69         * Used for skinning. 
     70         */ 
     71        public static final String CREATING_COLD_TEXT = "Creating cold text"; 
     72 
     73        private ResourceImportProvider provider; 
     74         
     75        /** 
     76         * Files for testing. 
     77         */ 
     78        public static final String[] FILES_TO_TEST =  
     79                new String[] {"text1.txt", "text2.txt", "pic1.jpg", "test.zip"}; 
     80         
     81        @SuppressWarnings("unchecked") 
     82        @Override 
     83        protected List<Class<? extends SophieModule>> fillDependencies() { 
     84                return Arrays.asList(BaseModelResourcesR4Module.class, 
     85                                BaseVisualModule.class, BaseMediaModule.class, 
     86                                BaseConfigModule.class, BasePersistenceModule.class, 
     87                                BaseCommonsModule.class, MainMediaNatlibModule.class, 
     88                                BaseDialogsModule.class, BoundModule.class, BaseSkinsModule.class, 
     89                                BaseModelBookModule.class, FileFunctionalityModule.class, 
     90                                MainAppModule.class, 
     91                                ColdTextModule.class); 
     92        } 
     93         
     94        @Override 
     95        @Before 
     96        protected void setUp() throws Exception { 
     97                super.setUp(); 
     98                 
     99                this.provider = new SimpleResourceImportProvider( 
     100                                new ColdTextImportManager(),  
     101                                new FileFilterInfo(ColdTextImportManager.FILE_FILTER)); 
     102        } 
     103         
     104        /** 
     105         * Tests if the {@link ResourceImportManager#generateChildRef()} 
     106         * is working correctly. 
     107         *  
     108         * @throws Exception 
     109         */ 
     110        @Test 
     111        public void testGenerateChildRef() throws Exception { 
     112                ColdTextImportManager manager =  
     113                        (ColdTextImportManager) this.provider.getImportManager(); 
     114                 
     115                ResourceRefR4 ref = manager.generateChildRef(); 
     116                 
     117                assertNotNull(ref); 
     118                assertTrue(ref.getLocation().contains(ColdTextResourceHelper.NAME_PREFIX)); 
     119        } 
     120         
     121        /** 
     122         * Tests the default retrieving of resource info. 
     123         *  
     124         * @throws Exception 
     125         */ 
     126        @Test 
     127        public void testRetrieveResourceInfo() throws Exception { 
     128                ColdTextImportManager manager =  
     129                        (ColdTextImportManager) this.provider.getImportManager(); 
     130                 
     131                File file1 = new File(FileEntryManager.get().getReadableFileEntry( 
     132                                FILES_TO_TEST[0]).getFile()); 
     133                File file2 = new File(FileEntryManager.get().getReadableFileEntry( 
     134                                FILES_TO_TEST[0]).getFile()); 
     135                 
     136                TestingDialogManager.get().expect(FileDialogInput.class,  
     137                                new FileContainer(file1, file2)); 
     138                 
     139                List<ResourceImportInfo<String>> infos =  
     140                        manager.retrieveResourceInfo(this.provider, null); 
     141                 
     142                assertEquals(2, infos.size()); 
     143                 
     144                ResourceImportInfo<String> info1 = infos.get(0); 
     145                assertNotNull(info1); 
     146                assertEquals(file1.getName(), info1.getName()); 
     147                assertEquals(file1.toURI(), info1.getImportOrigin()); 
     148                assertEquals(manager.getResourceData(file1, null), info1.getData()); 
     149                 
     150                ResourceImportInfo<String> info2 = infos.get(1); 
     151                assertNotNull(info2); 
     152                assertEquals(file2.getName(), info2.getName()); 
     153                assertEquals(file2.toURI(), info2.getImportOrigin()); 
     154                assertEquals(manager.getResourceData(file2, null), info2.getData()); 
     155                 
     156                // Test with file in other format: 
     157                File file3 = new File(FileEntryManager.get().getReadableFileEntry( 
     158                                FILES_TO_TEST[2]).getFile()); 
     159                 
     160                TestingDialogManager.get().expect(FileDialogInput.class,  
     161                                new FileContainer(file1, file3)); 
     162                 
     163                TestingDialogManager.get().expect(MessageDialogInput.class,  
     164                                null); 
     165                 
     166                infos =  
     167                        manager.retrieveResourceInfo(this.provider, null); 
     168                assertEquals(1, infos.size()); 
     169                 
     170                info1 = infos.get(0); 
     171                assertNotNull(info1); 
     172                assertEquals(file1.getName(), info1.getName()); 
     173                assertEquals(file1.toURI(), info1.getImportOrigin()); 
     174                assertEquals(manager.getResourceData(file1, null), info1.getData()); 
     175        } 
     176         
     177        /** 
     178         * Tests the {@link ResourceImportManager}'s inserting of frames. 
     179         *  
     180         * @throws Exception 
     181         */ 
     182        @Test 
     183        public void testInsertFrame() throws Exception { 
     184                ResourceAccess bookAccess = makeBookAccess(); 
     185                 
     186                final ResourceRefR4 coldRef =  
     187                        ResourceRefR4.generateRandomSub(ColdTextResource.DEFAULT_TITLE); 
     188                final String text = "Some text"; 
     189                 
     190                Message description = Message.create(CREATING_COLD_TEXT); 
     191                AutoAction action = new CreateColdTextAction(description, true, text, coldRef); 
     192                action.register(bookAccess); 
     193                 
     194                SubEntryNames children = ResourceR4.KEY_CHILDREN.get(bookAccess); 
     195                 
     196                // With the page : 
     197                assertEquals(2, children.size()); 
     198                 
     199                final ColdTextImportManager manager =  
     200                        (ColdTextImportManager) this.provider.getImportManager(); 
     201                 
     202                ResourceRefList pages = BookR4.KEY_PAGES.get(bookAccess); 
     203                assertEquals(1, pages.size()); 
     204                 
     205                final ResourceRefR4 parentRef = pages.get(0); 
     206                final ResourceRefR4 frameRef =  
     207                        ResourceRefR4.generateRandomSub(FrameH.NAME_PREFIX); 
     208                final ImmList<ActivationChannel> elements = ImmTreeList.empty(); 
     209                 
     210                description = Message.create(INSERT_THE_FRAME); 
     211                action = new InsertTextFrameAction(description, true, manager, frameRef, 
     212                                parentRef, elements, coldRef); 
     213                action.register(bookAccess); 
     214                 
     215                ChildrenKey pageChildrenKey =  
     216                        ResourceR4.KEY_CHILDREN.sub(parentRef).sub(ResourceR4.KEY_CHILDREN); 
     217                 
     218                SubEntryNames frames = pageChildrenKey.get(bookAccess); 
     219                 
     220                assertEquals(1, frames.size()); 
     221                 
     222                 TemplatedKey<ResourceRefR4> mainResKey =  
     223                         pageChildrenKey.sub(frameRef).sub(ResourceFrame.KEY_MAIN_RESOURCE); 
     224                 
     225                 ResourceRefR4 mainResRef = mainResKey.get(bookAccess); 
     226                  
     227                ResourceRefR4 pageToFrameRef = parentRef.append(frameRef); 
     228                ResourceRefR4 frameToContentRef = ResourceRefR4.getRelativeRef( 
     229                                pageToFrameRef, coldRef); 
     230                assertEquals(frameToContentRef, mainResRef); 
     231                 
     232        } 
     233         
     234} 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/logic/ResourceDeleteLogic.java

     
    2424import org.sophie2.main.app.commons.util.AppViewUtil; 
    2525import org.sophie2.main.dialogs.input.ConfirmDialogInput; 
    2626import org.sophie2.main.dialogs.input.DialogUtils; 
     27import org.sophie2.main.func.resources.actions.RemoveResourceAction; 
     28import org.sophie2.main.func.resources.actions.RemoveTemplateAction; 
    2729import org.sophie2.main.func.resources.view.ResourceDetailsPalette; 
    2830import org.sophie2.main.func.resources.view.ResourceDetailsPalette.DeleteResourceButton; 
    2931import org.sophie2.main.func.resources.view.ResourcesPalette.ResourceItem; 
     
    8486                        return true; 
    8587                } 
    8688        }; 
    87          
     89 
    8890        /** 
    8991         * Constant created for removing template. 
    9092         * Constant created to be a parameter of a message of an {@link AutoAction}.  
     
    122124 
    123125                final ResourceRefR4 resourceRef = ResourceRefR4.getRelativeRef( 
    124126                                bookAccess.getRef(), resource.getRef()); 
    125                 new AutoAction(Message.create(REMOVE_RESOURCE), true) { 
    126                         @Override 
    127                         public void performAuto() { 
    128                                 getChanger().removeResource(resourceRef); 
    129                         } 
     127                 
     128                Message description = Message.create(REMOVE_RESOURCE); 
     129                AutoAction action = new RemoveResourceAction(description, true, resourceRef); 
     130                action.register(bookAccess); 
    130131 
    131                 }.register(bookAccess); 
    132  
    133132                return true; 
    134133        } 
    135134 
     
    205204                ResourceAccess bookAccess = bookView.getAccess(); 
    206205                final ResourceRefList templates = key.get(bookAccess); 
    207206                if (templates.contains(ref)) { 
    208                         new AutoAction(Message.create(REMOVE_TEMPLATE), true) { 
    209                                 @Override 
    210                                 public void performAuto() { 
    211                                         getChanger().removeResource(ref); 
    212                                         getChanger().setRaw(key, templates.remove(ref)); 
    213                                 } 
    214  
    215                         }.register(bookAccess); 
     207                        Message description = Message.create(REMOVE_TEMPLATE); 
     208                        AutoAction action = new RemoveTemplateAction(description, true, templates, key, ref); 
     209                        action.register(bookAccess); 
    216210                         
    217211                        return true; 
    218212                } 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/ImportResourceAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     4import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     5import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 
     6import org.sophie2.base.skins.Message; 
     7import org.sophie2.main.func.resources.imports.ResourceImportInfo; 
     8import org.sophie2.main.func.resources.imports.ResourceImportManager; 
     9 
     10/** 
     11 * {@link AutoAction} for importing a new resource in a parent resource. 
     12 *  
     13 * @author meddle 
     14 * 
     15 * @param <D> 
     16 *                      The type of the import information needed to import the resource. 
     17 */ 
     18public class ImportResourceAction<D> extends AutoAction { 
     19         
     20        private final ResourceImportInfo<D> importInfo; 
     21        private final ResourceRefR4 resourceRef; 
     22        private final ResourceImportManager<D> importManager; 
     23 
     24        /** 
     25         * Creates the action with the import manager used to import the resource, 
     26         * the {@link ResourceImportInfo} needed for the import and the {@link ResourceRefR4} 
     27         * that will be pointing to the new resource. 
     28         *  
     29         * @param description  
     30         *                      Description of the action.  
     31         * @param significant  
     32         *                      Significance of the action.  
     33         * @param importInfo 
     34         *                      The info needed to import the resource. 
     35         * @param resourceRef 
     36         *                      The reference to the resource to import. 
     37         * @param importManager 
     38         *                      The import manager used to import the resource. 
     39         */ 
     40        public ImportResourceAction(Message description, boolean significant, 
     41                        ResourceImportInfo<D> importInfo, ResourceRefR4 resourceRef, 
     42                        ResourceImportManager<D> importManager) { 
     43                super(description, significant); 
     44                 
     45                this.importInfo = importInfo; 
     46                this.resourceRef = resourceRef; 
     47                this.importManager = importManager; 
     48        } 
     49 
     50        @Override 
     51        public void performAuto() { 
     52                ResourceChanger changer = getChanger(); 
     53 
     54                this.importManager.makeResource(changer, this.resourceRef, this.importInfo); 
     55        } 
     56} 
  • modules/org.sophie2.base.model.book/src/main/java/org/sophie2/base/model/book/resource/ResourceFilesUtil.java

     
    1 package org.sophie2.base.model.book.resource; 
    2  
    3 import java.io.File; 
    4 import java.io.FileInputStream; 
    5 import java.io.FileNotFoundException; 
    6 import java.io.FileOutputStream; 
    7 import java.io.IOException; 
    8 import java.util.UUID; 
    9  
    10 import org.sophie2.base.commons.util.bindata.BinData; 
    11 import org.sophie2.base.commons.util.bindata.ChunkedDataHolder; 
    12 import org.sophie2.base.commons.util.bindata.FileBinData; 
    13 import org.sophie2.base.commons.util.bindata.RawBinData; 
    14 import org.sophie2.base.model.resources.r4.LocationPrefix; 
    15 import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    16 import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    17 import org.sophie2.base.persistence.commons.PersistenceOptions; 
    18 import org.sophie2.base.persistence.commons.PersistenceUtil; 
    19 import org.sophie2.base.persistence.persister.MasterPersister; 
    20 import org.sophie2.base.persistence.ref.ValueRef; 
    21 import org.sophie2.base.persistence.storage.Storage; 
    22  
    23 /** 
    24  * Handles activities over outer files used by a Sophie 2.0 resource. 
    25  *  
    26  * @author meddle 
    27  */ 
    28 public final class ResourceFilesUtil { 
    29  
    30         /** 
    31          * The name of the directory the additional resource files are kept. 
    32          */ 
    33         public static final String FILES_DIRECTORY = "_files"; 
    34  
    35         /** 
    36          * The template saved when persisting relatively linked files. 
    37          */ 
    38         public static final String SAVEABLE_TEMPLATE = "${files_dir}"; 
    39  
    40         private static final String INSTANCE_RESOURCES_TEMP = UUID.randomUUID().toString(); 
    41          
    42         /** 
    43          * Stores a file to the special folder relative to 
    44          * a resource specified by {@link ResourceFilesUtil#FILES_DIRECTORY}. 
    45          *   
    46          * @param resource  
    47          *                      The resource that will use the stored file. 
    48          * @param file 
    49          *                      The file to store. 
    50          * @return 
    51          *                      True if the file is stored successfully. 
    52          */ 
    53         public static File storeFile(ResourceH resource, File file) { 
    54                 assert file != null && file.exists(); 
    55  
    56                 File filesDir = getFilesDir(resource); 
    57                 File resFile = new File(filesDir, file.getName()); 
    58  
    59                 boolean isTemp =  
    60                         filesDir.getAbsolutePath().startsWith(System.getProperty("java.io.tmpdir")); 
    61                 if (isTemp) { 
    62                         resFile.deleteOnExit(); 
    63                 } 
    64  
    65                 try { 
    66                         BinData.transport(new FileInputStream(file),  
    67                                         new FileOutputStream(resFile)); 
    68                         File originalFilesDir = getDir(file.getAbsolutePath()); 
    69                         if (originalFilesDir.exists()) { 
    70                                 copy(originalFilesDir, getFilesDir(resFile.getAbsolutePath()), 
    71                                                 isTemp); 
    72                         } 
    73  
    74                 } catch (FileNotFoundException e) { 
    75                         throw new RuntimeException(e); 
    76                 } catch (IOException e) { 
    77                         throw new RuntimeException(e); 
    78                 } 
    79  
    80                 return resFile; 
    81         } 
    82  
    83         /** 
    84          * Retrieves the additional files directory for a given resource. 
    85          * If it does not exists creates it. 
    86          *  
    87          * @param resource 
    88          *                      The resource for which the files directory will be retrieved. 
    89          * @return 
    90          *                      The directory. 
    91          */ 
    92         public static File getFilesDir(ResourceH resource) { 
    93                 assert resource != null; 
    94  
    95                 return getFilesDir(resource.getRef().getLocation()); 
    96         } 
    97  
    98         /** 
    99          * Checks if the additional files directory for the passed 
    100          * resource exists or not. 
    101          *  
    102          * @param resource 
    103          *                      The resource to check the directory for. 
    104          * @return 
    105          *                      True if the directory exists, false otherwise. 
    106          */ 
    107         public static boolean hasFileDirectory(ResourceH resource) { 
    108                 return getDir(resource.getRef().getLocation()).exists(); 
    109         } 
    110  
    111         /** 
    112          * Retrieves the additional files directory for a given resource location. 
    113          * If it does not exists creates it. 
    114          *  
    115          * @param resourceLocation 
    116          *                      The location of the resource for which the  
    117          *                      files directory will be retrieved. 
    118          * @return 
    119          *                      The directory. 
    120          */ 
    121         public static File getFilesDir(String resourceLocation) { 
    122                 File filesDir = getDir(resourceLocation); 
    123                 if (!filesDir.exists()) { 
    124                         assert filesDir.mkdirs() : "Cannot create resource directory."; 
    125                 } 
    126  
    127                 return filesDir; 
    128         } 
    129  
    130         /** 
    131          * Checks if the passed {@link ResourceRefR4} points to a resource in the directory, 
    132          * relative to the passed <var>parentLocation</var> 
    133          *  
    134          * @param ref 
    135          *                      The ref to check. 
    136          * @param parentLocation 
    137          *                      The parent location to check. 
    138          * @return 
    139          *                      True if the ref is relative. 
    140          */ 
    141         public static boolean isRelativeToParent(ResourceRefR4 ref, String parentLocation) { 
    142                 File parentDir = ResourceFilesUtil.getDir(parentLocation); 
    143                 String parentDirLocation = parentDir.getAbsolutePath().replace( 
    144                                 File.separator, ResourceRefR4.SEPARATOR); 
    145                 String location = ref.getLocation(); 
    146  
    147                 if (location.contains(parentDirLocation) 
    148                                 || location.contains(ResourceFilesUtil.FILES_DIRECTORY)) { 
    149                         return true; 
    150                 } 
    151  
    152                 return false; 
    153         } 
    154  
    155         private static String getDirName(String resourceLocation, int lastSeparator) { 
    156                 return resourceLocation.substring( 
    157                                 lastSeparator + 1, resourceLocation.length()).replace( 
    158                                                 ".", "_") + FILES_DIRECTORY; 
    159         } 
    160          
    161         private static File getDir(String resourceLocation) { 
    162                 // Temp dir: 
    163                 if (resourceLocation.startsWith(LocationPrefix.MEMORY) 
    164                                 || resourceLocation.startsWith(LocationPrefix.SERVER)) { 
    165                         int start = resourceLocation.indexOf("://") + 2; 
    166  
    167                         String parent = System.getProperty("java.io.tmpdir"); 
    168                         String pathname = INSTANCE_RESOURCES_TEMP + resourceLocation.substring(start) + FILES_DIRECTORY; 
    169                         pathname = parent + File.separator + pathname.replaceAll(":", "_"); 
    170                         File tempDir = new File(pathname); 
    171  
    172                         if (!tempDir.exists()) { 
    173                                 tempDir.deleteOnExit(); 
    174                         } 
    175  
    176                         return tempDir; 
    177                 } 
    178  
    179                 int lastSeparator = resourceLocation.lastIndexOf(File.separator); 
    180  
    181                 String resourceName = getDirName(resourceLocation, lastSeparator); 
    182  
    183                 String dirName = resourceLocation.substring(0, lastSeparator) + 
    184                 File.separator + resourceName; 
    185  
    186                 dirName = dirName.replace( 
    187                                 File.separator, ResourceRefR4.SEPARATOR); 
    188                 if (dirName.startsWith(LocationPrefix.FILE)) { 
    189                         dirName = dirName.substring(LocationPrefix.FILE.length()); 
    190                 } 
    191  
    192                 return new File(dirName); 
    193         } 
    194  
    195         /** 
    196          * Retrieves a valid path for constructing a file. 
    197          *  
    198          * @param path 
    199          *                      The path to create valid one. 
    200          * @return 
    201          *                      The valid path. 
    202          */ 
    203         public static String getValidPath(String path) { 
    204                 String validPath = path.replace( 
    205                                 File.separator, ResourceRefR4.SEPARATOR); 
    206                 if (validPath.startsWith(LocationPrefix.FILE)) { 
    207                         validPath = validPath.substring(LocationPrefix.FILE.length()); 
    208                 } 
    209  
    210                 return validPath; 
    211         } 
    212  
    213         /** 
    214          * Retrieves a save-able location that can be loaded even 
    215          * if the file containing it is moved. 
    216          *  
    217          * If the file path is <tt>../some_dir/file.txt</tt>, 
    218          * the new one will be <tt>../{@link ResourceFilesUtil#SAVEABLE_TEMPLATE}/file.text</tt>. 
    219          *  
    220          * @param parentPath 
    221          *                      The path of the parent file where the location will be saved. 
    222          * @param file 
    223          *                      The file which location will be saved 
    224          * @return 
    225          *                      The location. 
    226          */ 
    227         public static String getSaveableLocation(String parentPath, File file) { 
    228                 if (parentPath == null) { 
    229                         return file.getAbsolutePath(); 
    230                 } 
    231  
    232                 int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
    233                 String dirName = getDirName(parentPath, lastSeparator);  
    234  
    235                 File targetFile = new File(getDir(parentPath), file.getName());  
    236  
    237                 ResourceRefR4 relative = ResourceRefR4.getRelativeRef( 
    238                                 ResourceRefR4.make(parentPath), ResourceRefR4.make(targetFile)); 
    239  
    240  
    241                 return relative.getLocation().replace(dirName, SAVEABLE_TEMPLATE); 
    242         } 
    243  
    244         /** 
    245          * Retrieves save-able resource ref to a relatively linked resource. 
    246          *  
    247          * @see ResourceFilesUtil#getSaveableLocation(String, File) 
    248          *  
    249          * @param parentPath 
    250          *                      The path of the parent resource containing the link. 
    251          * @param ref 
    252          *                      The absolute ref to the linked resource. 
    253          * @return 
    254          *                      The save-able ref.  
    255          */ 
    256         public static ResourceRefR4 getSaveableRef(String parentPath, ResourceRefR4 ref) { 
    257                 if (parentPath == null) { 
    258                         return ref; 
    259                 } 
    260  
    261                 int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
    262                 String dirName = getDirName(parentPath, lastSeparator);  
    263  
    264                 ResourceRefR4 targetRef = ref; 
    265                 if (!targetRef.getLocation().contains(dirName)) { 
    266                         targetRef = ResourceRefR4.make(new File(getDir(parentPath), ref.getName()));  
    267                 } 
    268  
    269                 ResourceRefR4 relative = ResourceRefR4.getRelativeRef( 
    270                                 ResourceRefR4.make(parentPath), targetRef); 
    271  
    272  
    273                 return ResourceRefR4.make( 
    274                                 relative.getLocation().replace(dirName, SAVEABLE_TEMPLATE)); 
    275         } 
    276  
    277         /** 
    278          * Restores the original path to a file to load from a string generated by 
    279          * {@link ResourceFilesUtil#getSaveableLocation(String, File)}.  
    280          *  
    281          * @param parentPath 
    282          *                      The parent file from which the location will be loaded. 
    283          * @param saveablePath 
    284          *                      The save-able path. 
    285          * @return 
    286          *                      The location that is loadable. 
    287          */ 
    288         public static String getLoadableLocation(String parentPath, String saveablePath) { 
    289                 if (parentPath == null) { 
    290                         return saveablePath; 
    291                 } 
    292  
    293                 ResourceRefR4 absolute = ResourceRefR4.make( 
    294                                 parentPath).append(ResourceRefR4.make(saveablePath)); 
    295  
    296                 int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
    297  
    298                 return absolute.getLocation().replace( 
    299                                 SAVEABLE_TEMPLATE, getDirName(parentPath, lastSeparator)); 
    300         } 
    301  
    302         /** 
    303          * Restores the original {@link ResourceRefR4} to a linked relatively resource 
    304          * from the one generated by {@link ResourceFilesUtil#getSaveableRef(String, ResourceRefR4)}. 
    305          *  
    306          * @see ResourceFilesUtil#getSaveableRef(String, ResourceRefR4) 
    307          * @see ResourceFilesUtil#getLoadableLocation(String, String) 
    308          *  
    309          * @param parentPath 
    310          *                      The path of the parent resource containing the link. 
    311          * @param loadedRef 
    312          *                      The ref containing a save-able template. 
    313          *  
    314          * @see ResourceFilesUtil#getSaveableRef(String, ResourceRefR4) 
    315          *  
    316          * @return 
    317          *                      The generated ref. 
    318          */ 
    319         public static ResourceRefR4 getLoadableRef(String parentPath, ResourceRefR4 loadedRef) { 
    320                 if (parentPath == null || !loadedRef.getLocation().contains(SAVEABLE_TEMPLATE)) { 
    321                         return loadedRef; 
    322                 } 
    323  
    324                 ResourceRefR4 absolute = ResourceRefR4.make( 
    325                                 parentPath).append(loadedRef); 
    326  
    327                 int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
    328  
    329                 return ResourceRefR4.make(absolute.getLocation().replace( 
    330                                 SAVEABLE_TEMPLATE, getDirName(parentPath, lastSeparator))); 
    331         } 
    332  
    333         /** 
    334          * Saves a resource file in such a way, that it can be loaded even if  
    335          * the resource that links it is moved along with the its relative directory. 
    336          *  
    337          * @param parentPath 
    338          *                      The path to the parent file that will contain the location 
    339          *                      of the resource file. 
    340          * @param filePath 
    341          *                      The path to the file to save. 
    342          * @param original 
    343          *                      The original file which will be copied and saved to a new location. 
    344          */ 
    345         public static void saveLoadableResource(String parentPath, String filePath, File original) { 
    346                 File target = new File( 
    347                                 getValidPath(getLoadableLocation(parentPath, filePath))); 
    348                 if (!target.exists()) { 
    349                         if (parentPath == null) { 
    350                                 String validParentPath = filePath.substring(0, 
    351                                                 filePath.lastIndexOf(File.separator)); 
    352                                 File validParentDir = new File(validParentPath); 
    353                                 if (!validParentDir.exists()) { 
    354                                         validParentDir.mkdir(); 
    355                                 } 
    356                         } else { 
    357                                 getFilesDir(parentPath); // Create dir if not exists 
    358                         } 
    359  
    360                         copy(original, target, false); 
    361                 } 
    362         } 
    363  
    364         /** 
    365          * Copies the additional files directory of the 
    366          * resource with location the passed <var>originalResLocation</var> 
    367          * to the additional file directory of the resource with location 
    368          * the passed <var>targetResLocation</var>. 
    369          *  
    370          * @param originalResLocation 
    371          *                      The location of the resource which directory will be copied. 
    372          * @param targetResLocation 
    373          *                      The location of the resource which directory will be filled. 
    374          */ 
    375         public static void copyResourceDir( 
    376                         String originalResLocation, String targetResLocation) { 
    377                 File original = getDir(originalResLocation); 
    378                 if (original != null && original.exists()) { 
    379                         File target = getFilesDir(targetResLocation); 
    380  
    381                         String tmpDir = System.getProperty("java.io.tmpdir"); 
    382                         boolean delOnExit = target.getAbsolutePath().startsWith(tmpDir); 
    383                         copy(original, target, delOnExit); 
    384                 } 
    385         } 
    386  
    387  
    388         private static void copy(File original, File target, boolean deleteOnExit) { 
    389                 if (!original.exists()) { 
    390                         return; 
    391                 } 
    392  
    393                 if (original.isDirectory()) { 
    394                         if (!target.exists()) { 
    395                                 assert target.mkdirs(); 
    396                         } 
    397  
    398                         for (File file : original.listFiles()) { 
    399                                 copy(file, new File(target, file.getName()), deleteOnExit); 
    400                         } 
    401                 } else { 
    402                         if (!target.exists()) { 
    403                                 try { 
    404                                         target.createNewFile(); 
    405                                 } catch (IOException e) { 
    406                                         throw new RuntimeException(e); 
    407                                 } 
    408                         } 
    409                         try { 
    410                                 BinData.transport(new FileInputStream(original), new FileOutputStream(target)); 
    411                                 File originalFilesDir = getDir(original.getAbsolutePath()); 
    412                                 if (originalFilesDir.exists()) { 
    413                                         copy(originalFilesDir, getDir(target.getAbsolutePath()), deleteOnExit); 
    414                                 } 
    415  
    416                                 if (deleteOnExit) { 
    417                                         target.deleteOnExit(); 
    418                                 } 
    419                         } catch (FileNotFoundException e) { 
    420                                 throw new RuntimeException(e); 
    421                         } catch (IOException e) { 
    422                                 throw new RuntimeException(e); 
    423                         } 
    424                 } 
    425         } 
    426  
    427         /** 
    428          * Helper method for persisting binary data. Takes in mind the type of the 
    429          * data to persist (linked, embedded and so on...). 
    430          *  
    431          * @param ref 
    432          *                      The {@link ValueRef} for the bean data to persist. 
    433          * @param storage 
    434          *                      The storage in which to persist. 
    435          * @param options 
    436          *                      The {@link PersistenceOptions}. 
    437          * @param format 
    438          *                      The format of the data to persist. Linked, embedded, relatively linked, etc... 
    439          * @param embeddedFileName 
    440          *                      The name of the file in which the data will be embedded  
    441          *                      if the format means embedding. 
    442          * @throws IOException 
    443          *                      If the data can not be persisted. 
    444          */ 
    445         public static void persistBinData(final ValueRef<BinData> ref, Storage storage, 
    446                         final PersistenceOptions options, String format, String embeddedFileName) throws IOException { 
    447                 if (options.isSaveMode() && ref.get() == null) { 
    448                         return; 
    449                 } 
    450                 if (options.isLoadMode() && storage.getAttribute("src") == null) { 
    451                         ref.set(null); 
    452                         return; 
    453                 } 
    454  
    455                 ValueRef<ResourceDataPersistType> enumRef = new ValueRef<ResourceDataPersistType>(); 
    456                 if (options.isSaveMode()) { 
    457                         enumRef.set(ResourceDataPersistType.getPersistType(ref.get())); 
    458                 } 
    459  
    460                 if (options.isLoadMode() && storage.getChild("dataType") == null) { 
    461                         storage.child("dataType").setTextContent(ResourceDataPersistType.EMBEDDED.name()); 
    462                 } 
    463  
    464                 MasterPersister.persist(enumRef, storage.child("dataType"), 
    465                                 options, PersistenceUtil.getStorageR3Schema(ResourceDataPersistType.class)); 
    466  
    467                 if (ResourceDataPersistType.EMBEDDED == enumRef.get()) { 
    468                         MasterPersister.persist(ref, storage.getParent().getParent().getParent().attribute( 
    469                         "_data").attribute(embeddedFileName), options, 
    470                         PersistenceUtil.getStorageR3Schema(RawBinData.class)); 
    471                         if (options.isSaveMode()) { 
    472                                 storage.attribute("src").setTextContent("./_data/" + embeddedFileName); 
    473                         } 
    474                 } else if (ResourceDataPersistType.CHUNKED == enumRef.get()) { 
    475                         if (options.isSaveMode()) { 
    476                                 ChunkedDataHolder holder = (ChunkedDataHolder) ref.get(); 
    477                                 ref.set(holder.getChunkedBinData()); 
    478                         } 
    479                          
    480                         MasterPersister.persist(ref, storage, options,  
    481                                         PersistenceUtil.getStorageR3Schema(ChunkedDataHolder.class)); 
    482                 } else { 
    483                         if (options.isSaveMode()) { 
    484                                 FileBinData fileData = (FileBinData) ref.get(); 
    485  
    486                                 if (ResourceDataPersistType.LINKED_ABSOLUTE == enumRef.get()) { 
    487                                         storage.attribute("src").setTextContent(fileData.getFile().getPath()); 
    488                                 } else { 
    489                                         String parent = options.get(PersistenceUtil.LOCATION); 
    490  
    491                                         String source = ResourceFilesUtil.getSaveableLocation( 
    492                                                         parent, fileData.getFile()); 
    493                                         ResourceFilesUtil.saveLoadableResource(parent, 
    494                                                         source, fileData.getFile()); 
    495  
    496                                         storage.attribute("src").setTextContent(source); 
    497                                 } 
    498                         } else { 
    499                                 assert options.isLoadMode(); 
    500  
    501                                 File sourceFile = null; 
    502                                 String path = storage.attribute("src").getTextContent(); 
    503  
    504                                 if (ResourceDataPersistType.LINKED_RELATIVE == enumRef.get()) { 
    505                                         String parent = options.get(PersistenceUtil.LOCATION); 
    506  
    507                                         String source = ResourceFilesUtil.getLoadableLocation( 
    508                                                         parent, path); 
    509                                         sourceFile = new File(ResourceFilesUtil.getValidPath(source)); 
    510                                 } else { 
    511                                         assert ResourceDataPersistType.LINKED_ABSOLUTE == enumRef.get(); 
    512  
    513                                         sourceFile = new File(path); 
    514                                 } 
    515  
    516                                 ref.set(FileBinData.create(sourceFile, 
    517                                                 ResourceDataPersistType.LINKED_ABSOLUTE == enumRef.get())); 
    518                         } 
    519                 } 
    520         } 
    521  
    522 } 
     1package org.sophie2.base.model.book.resource; 
     2 
     3import java.io.File; 
     4import java.io.FileInputStream; 
     5import java.io.FileNotFoundException; 
     6import java.io.FileOutputStream; 
     7import java.io.IOException; 
     8import java.util.UUID; 
     9 
     10import org.sophie2.base.commons.util.bindata.BinData; 
     11import org.sophie2.base.commons.util.bindata.ChunkedDataHolder; 
     12import org.sophie2.base.commons.util.bindata.FileBinData; 
     13import org.sophie2.base.commons.util.bindata.RawBinData; 
     14import org.sophie2.base.model.resources.r4.LocationPrefix; 
     15import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     16import org.sophie2.base.model.resources.r4.resources.ResourceH; 
     17import org.sophie2.base.persistence.commons.PersistenceOptions; 
     18import org.sophie2.base.persistence.commons.PersistenceUtil; 
     19import org.sophie2.base.persistence.persister.MasterPersister; 
     20import org.sophie2.base.persistence.ref.ValueRef; 
     21import org.sophie2.base.persistence.storage.Storage; 
     22 
     23/** 
     24 * Handles activities over outer files used by a Sophie 2.0 resource. 
     25 *  
     26 * @author meddle 
     27 */ 
     28public final class ResourceFilesUtil { 
     29 
     30        /** 
     31         * The name of the directory the additional resource files are kept. 
     32         */ 
     33        public static final String FILES_DIRECTORY = "_files"; 
     34 
     35        /** 
     36         * The template saved when persisting relatively linked files. 
     37         */ 
     38        public static final String SAVEABLE_TEMPLATE = "${files_dir}"; 
     39 
     40        private static final String INSTANCE_RESOURCES_TEMP = UUID.randomUUID().toString(); 
     41         
     42        /** 
     43         * The file separator used for storing files from Sophie. 
     44         */ 
     45        public static final String FILE_SEPARATOR = "/"; 
     46         
     47        /** 
     48         * Stores a file to the special folder relative to 
     49         * a resource specified by {@link ResourceFilesUtil#FILES_DIRECTORY}. 
     50         *   
     51         * @param resource  
     52         *                      The resource that will use the stored file. 
     53         * @param file 
     54         *                      The file to store. 
     55         * @return 
     56         *                      True if the file is stored successfully. 
     57         */ 
     58        public static File storeFile(ResourceH resource, File file) { 
     59                assert file != null && file.exists(); 
     60 
     61                File filesDir = getFilesDir(resource); 
     62                File resFile = new File(filesDir, file.getName()); 
     63 
     64                boolean isTemp =  
     65                        filesDir.getAbsolutePath().startsWith(System.getProperty("java.io.tmpdir")); 
     66                if (isTemp) { 
     67                        resFile.deleteOnExit(); 
     68                } 
     69 
     70                try { 
     71                        BinData.transport(new FileInputStream(file),  
     72                                        new FileOutputStream(resFile)); 
     73                        File originalFilesDir = getDir(file.getAbsolutePath()); 
     74                        if (originalFilesDir.exists()) { 
     75                                copy(originalFilesDir, getFilesDir(resFile.getAbsolutePath()), 
     76                                                isTemp); 
     77                        } 
     78 
     79                } catch (FileNotFoundException e) { 
     80                        throw new RuntimeException(e); 
     81                } catch (IOException e) { 
     82                        throw new RuntimeException(e); 
     83                } 
     84 
     85                return resFile; 
     86        } 
     87 
     88        /** 
     89         * Retrieves the additional files directory for a given resource. 
     90         * If it does not exists creates it. 
     91         *  
     92         * @param resource 
     93         *                      The resource for which the files directory will be retrieved. 
     94         * @return 
     95         *                      The directory. 
     96         */ 
     97        public static File getFilesDir(ResourceH resource) { 
     98                assert resource != null; 
     99 
     100                return getFilesDir(resource.getRef().getLocation()); 
     101        } 
     102 
     103        /** 
     104         * Checks if the additional files directory for the passed 
     105         * resource exists or not. 
     106         *  
     107         * @param resource 
     108         *                      The resource to check the directory for. 
     109         * @return 
     110         *                      True if the directory exists, false otherwise. 
     111         */ 
     112        public static boolean hasFileDirectory(ResourceH resource) { 
     113                return getDir(resource.getRef().getLocation()).exists(); 
     114        } 
     115 
     116        /** 
     117         * Retrieves the additional files directory for a given resource location. 
     118         * If it does not exists creates it. 
     119         *  
     120         * @param resourceLocation 
     121         *                      The location of the resource for which the  
     122         *                      files directory will be retrieved. 
     123         * @return 
     124         *                      The directory. 
     125         */ 
     126        public static File getFilesDir(String resourceLocation) { 
     127                File filesDir = getDir(resourceLocation); 
     128                if (!filesDir.exists()) { 
     129                        assert filesDir.mkdirs() : "Cannot create resource directory."; 
     130                } 
     131 
     132                return filesDir; 
     133        } 
     134 
     135        /** 
     136         * Checks if the passed {@link ResourceRefR4} points to a resource in the directory, 
     137         * relative to the passed <var>parentLocation</var> 
     138         *  
     139         * @param ref 
     140         *                      The ref to check. 
     141         * @param parentLocation 
     142         *                      The parent location to check. 
     143         * @return 
     144         *                      True if the ref is relative. 
     145         */ 
     146        public static boolean isRelativeToParent(ResourceRefR4 ref, String parentLocation) { 
     147                File parentDir = ResourceFilesUtil.getDir(parentLocation); 
     148                String parentDirLocation = parentDir.getAbsolutePath().replace( 
     149                                File.separator, FILE_SEPARATOR); 
     150                String location = ref.getLocation(); 
     151 
     152                if (location.contains(parentDirLocation) 
     153                                || location.contains(ResourceFilesUtil.FILES_DIRECTORY)) { 
     154                        return true; 
     155                } 
     156 
     157                return false; 
     158        } 
     159 
     160        private static String getDirName(String resourceLocation, int lastSeparator) { 
     161                return resourceLocation.substring( 
     162                                lastSeparator + 1, resourceLocation.length()).replace( 
     163                                                ".", "_") + FILES_DIRECTORY; 
     164        } 
     165         
     166        private static File getDir(String resourceLocation) { 
     167                resourceLocation = resourceLocation.replace(File.separator, FILE_SEPARATOR); 
     168                 
     169                // Temp dir: 
     170                if (resourceLocation.startsWith(LocationPrefix.MEMORY) 
     171                                || resourceLocation.startsWith(LocationPrefix.SERVER)) { 
     172                        int start = resourceLocation.indexOf("://") + 2; 
     173 
     174                        String parent = System.getProperty("java.io.tmpdir"); 
     175                        String pathname = INSTANCE_RESOURCES_TEMP + resourceLocation.substring(start) + FILES_DIRECTORY; 
     176                        pathname = parent + FILE_SEPARATOR + pathname.replaceAll(":", "_"); 
     177                        File tempDir = new File(pathname); 
     178 
     179                        if (!tempDir.exists()) { 
     180                                tempDir.deleteOnExit(); 
     181                        } 
     182 
     183                        return tempDir; 
     184                } 
     185 
     186                int lastSeparator = resourceLocation.lastIndexOf(FILE_SEPARATOR); 
     187 
     188                String resourceName = getDirName(resourceLocation, lastSeparator); 
     189 
     190                String dirName = resourceLocation.substring(0, lastSeparator) + 
     191                FILE_SEPARATOR + resourceName; 
     192 
     193                dirName = dirName.replace( 
     194                                File.separator, FILE_SEPARATOR); 
     195                if (dirName.startsWith(LocationPrefix.FILE)) { 
     196                        dirName = dirName.substring(LocationPrefix.FILE.length()); 
     197                } 
     198 
     199                return new File(dirName); 
     200        } 
     201 
     202        /** 
     203         * Retrieves a valid path for constructing a file. 
     204         *  
     205         * @param path 
     206         *                      The path to create valid one. 
     207         * @return 
     208         *                      The valid path. 
     209         */ 
     210        public static String getValidPath(String path) { 
     211                String validPath = path.replace( 
     212                                File.separator, FILE_SEPARATOR); 
     213                if (validPath.startsWith(LocationPrefix.FILE)) { 
     214                        validPath = validPath.substring(LocationPrefix.FILE.length()); 
     215                } 
     216 
     217                return validPath; 
     218        } 
     219 
     220        /** 
     221         * Retrieves a save-able location that can be loaded even 
     222         * if the file containing it is moved. 
     223         *  
     224         * If the file path is <tt>../some_dir/file.txt</tt>, 
     225         * the new one will be <tt>../{@link ResourceFilesUtil#SAVEABLE_TEMPLATE}/file.text</tt>. 
     226         *  
     227         * @param parentPath 
     228         *                      The path of the parent file where the location will be saved. 
     229         * @param file 
     230         *                      The file which location will be saved 
     231         * @return 
     232         *                      The location. 
     233         */ 
     234        public static String getSaveableLocation(String parentPath, File file) { 
     235                if (parentPath == null) { 
     236                        return file.getAbsolutePath(); 
     237                } 
     238 
     239                int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
     240                String dirName = getDirName(parentPath, lastSeparator);  
     241 
     242                File targetFile = new File(getDir(parentPath), file.getName());  
     243 
     244                ResourceRefR4 relative = ResourceRefR4.getRelativeRef( 
     245                                ResourceRefR4.make(parentPath), ResourceRefR4.make(targetFile)); 
     246 
     247 
     248                return relative.getLocation().replace(dirName, SAVEABLE_TEMPLATE); 
     249        } 
     250 
     251        /** 
     252         * Retrieves save-able resource ref to a relatively linked resource. 
     253         *  
     254         * @see ResourceFilesUtil#getSaveableLocation(String, File) 
     255         *  
     256         * @param parentPath 
     257         *                      The path of the parent resource containing the link. 
     258         * @param ref 
     259         *                      The absolute ref to the linked resource. 
     260         * @return 
     261         *                      The save-able ref.  
     262         */ 
     263        public static ResourceRefR4 getSaveableRef(String parentPath, ResourceRefR4 ref) { 
     264                if (parentPath == null) { 
     265                        return ref; 
     266                } 
     267 
     268                int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
     269                String dirName = getDirName(parentPath, lastSeparator);  
     270 
     271                ResourceRefR4 targetRef = ref; 
     272                if (!targetRef.getLocation().contains(dirName)) { 
     273                        targetRef = ResourceRefR4.make(new File(getDir(parentPath), ref.getName()));  
     274                } 
     275 
     276                ResourceRefR4 relative = ResourceRefR4.getRelativeRef( 
     277                                ResourceRefR4.make(parentPath), targetRef); 
     278 
     279 
     280                return ResourceRefR4.make( 
     281                                relative.getLocation().replace(dirName, SAVEABLE_TEMPLATE)); 
     282        } 
     283 
     284        /** 
     285         * Restores the original path to a file to load from a string generated by 
     286         * {@link ResourceFilesUtil#getSaveableLocation(String, File)}.  
     287         *  
     288         * @param parentPath 
     289         *                      The parent file from which the location will be loaded. 
     290         * @param saveablePath 
     291         *                      The save-able path. 
     292         * @return 
     293         *                      The location that is loadable. 
     294         */ 
     295        public static String getLoadableLocation(String parentPath, String saveablePath) { 
     296                if (parentPath == null) { 
     297                        return saveablePath; 
     298                } 
     299 
     300                ResourceRefR4 absolute = ResourceRefR4.make( 
     301                                parentPath).append(ResourceRefR4.make(saveablePath)); 
     302 
     303                int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
     304 
     305                return absolute.getLocation().replace( 
     306                                SAVEABLE_TEMPLATE, getDirName(parentPath, lastSeparator)); 
     307        } 
     308 
     309        /** 
     310         * Restores the original {@link ResourceRefR4} to a linked relatively resource 
     311         * from the one generated by {@link ResourceFilesUtil#getSaveableRef(String, ResourceRefR4)}. 
     312         *  
     313         * @see ResourceFilesUtil#getSaveableRef(String, ResourceRefR4) 
     314         * @see ResourceFilesUtil#getLoadableLocation(String, String) 
     315         *  
     316         * @param parentPath 
     317         *                      The path of the parent resource containing the link. 
     318         * @param loadedRef 
     319         *                      The ref containing a save-able template. 
     320         *  
     321         * @see ResourceFilesUtil#getSaveableRef(String, ResourceRefR4) 
     322         *  
     323         * @return 
     324         *                      The generated ref. 
     325         */ 
     326        public static ResourceRefR4 getLoadableRef(String parentPath, ResourceRefR4 loadedRef) { 
     327                if (parentPath == null || !loadedRef.getLocation().contains(SAVEABLE_TEMPLATE)) { 
     328                        return loadedRef; 
     329                } 
     330 
     331                ResourceRefR4 absolute = ResourceRefR4.make( 
     332                                parentPath).append(loadedRef); 
     333 
     334                int lastSeparator = parentPath.lastIndexOf(ResourceRefR4.SEPARATOR); 
     335 
     336                return ResourceRefR4.make(absolute.getLocation().replace( 
     337                                SAVEABLE_TEMPLATE, getDirName(parentPath, lastSeparator))); 
     338        } 
     339 
     340        /** 
     341         * Saves a resource file in such a way, that it can be loaded even if  
     342         * the resource that links it is moved along with the its relative directory. 
     343         *  
     344         * @param parentPath 
     345         *                      The path to the parent file that will contain the location 
     346         *                      of the resource file. 
     347         * @param filePath 
     348         *                      The path to the file to save. 
     349         * @param original 
     350         *                      The original file which will be copied and saved to a new location. 
     351         */ 
     352        public static void saveLoadableResource(String parentPath, String filePath, File original) { 
     353                File target = new File( 
     354                                getValidPath(getLoadableLocation(parentPath, filePath))); 
     355                if (!target.exists()) { 
     356                        if (parentPath == null) { 
     357                                String validParentPath = filePath.substring(0, 
     358                                                filePath.lastIndexOf(FILE_SEPARATOR)); 
     359                                File validParentDir = new File(validParentPath); 
     360                                if (!validParentDir.exists()) { 
     361                                        validParentDir.mkdir(); 
     362                                } 
     363                        } else { 
     364                                getFilesDir(parentPath); // Create dir if not exists 
     365                        } 
     366 
     367                        copy(original, target, false); 
     368                } 
     369        } 
     370 
     371        /** 
     372         * Copies the additional files directory of the 
     373         * resource with location the passed <var>originalResLocation</var> 
     374         * to the additional file directory of the resource with location 
     375         * the passed <var>targetResLocation</var>. 
     376         *  
     377         * @param originalResLocation 
     378         *                      The location of the resource which directory will be copied. 
     379         * @param targetResLocation 
     380         *                      The location of the resource which directory will be filled. 
     381         */ 
     382        public static void copyResourceDir( 
     383                        String originalResLocation, String targetResLocation) { 
     384                File original = getDir(originalResLocation); 
     385                if (original != null && original.exists()) { 
     386                        File target = getFilesDir(targetResLocation); 
     387 
     388                        String tmpDir = System.getProperty("java.io.tmpdir"); 
     389                        boolean delOnExit = target.getAbsolutePath().startsWith(tmpDir); 
     390                        copy(original, target, delOnExit); 
     391                } 
     392        } 
     393 
     394 
     395        private static void copy(File original, File target, boolean deleteOnExit) { 
     396                if (!original.exists()) { 
     397                        return; 
     398                } 
     399 
     400                if (original.isDirectory()) { 
     401                        if (!target.exists()) { 
     402                                assert target.mkdirs(); 
     403                        } 
     404 
     405                        for (File file : original.listFiles()) { 
     406                                copy(file, new File(target, file.getName()), deleteOnExit); 
     407                        } 
     408                } else { 
     409                        if (!target.exists()) { 
     410                                try { 
     411                                        target.createNewFile(); 
     412                                } catch (IOException e) { 
     413                                        throw new RuntimeException(e); 
     414                                } 
     415                        } 
     416                        try { 
     417                                BinData.transport(new FileInputStream(original), new FileOutputStream(target)); 
     418                                File originalFilesDir = getDir(original.getAbsolutePath()); 
     419                                if (originalFilesDir.exists()) { 
     420                                        copy(originalFilesDir, getDir(target.getAbsolutePath()), deleteOnExit); 
     421                                } 
     422 
     423                                if (deleteOnExit) { 
     424                                        target.deleteOnExit(); 
     425                                } 
     426                        } catch (FileNotFoundException e) { 
     427                                throw new RuntimeException(e); 
     428                        } catch (IOException e) { 
     429                                throw new RuntimeException(e); 
     430                        } 
     431                } 
     432        } 
     433 
     434        /** 
     435         * Helper method for persisting binary data. Takes in mind the type of the 
     436         * data to persist (linked, embedded and so on...). 
     437         *  
     438         * @param ref 
     439         *                      The {@link ValueRef} for the bean data to persist. 
     440         * @param storage 
     441         *                      The storage in which to persist. 
     442         * @param options 
     443         *                      The {@link PersistenceOptions}. 
     444         * @param format 
     445         *                      The format of the data to persist. Linked, embedded, relatively linked, etc... 
     446         * @param embeddedFileName 
     447         *                      The name of the file in which the data will be embedded  
     448         *                      if the format means embedding. 
     449         * @throws IOException 
     450         *                      If the data can not be persisted. 
     451         */ 
     452        public static void persistBinData(final ValueRef<BinData> ref, Storage storage, 
     453                        final PersistenceOptions options, String format, String embeddedFileName) throws IOException { 
     454                if (options.isSaveMode() && ref.get() == null) { 
     455                        return; 
     456                } 
     457                if (options.isLoadMode() && storage.getAttribute("src") == null) { 
     458                        ref.set(null); 
     459                        return; 
     460                } 
     461 
     462                ValueRef<ResourceDataPersistType> enumRef = new ValueRef<ResourceDataPersistType>(); 
     463                if (options.isSaveMode()) { 
     464                        enumRef.set(ResourceDataPersistType.getPersistType(ref.get())); 
     465                } 
     466 
     467                if (options.isLoadMode() && storage.getChild("dataType") == null) { 
     468                        storage.child("dataType").setTextContent(ResourceDataPersistType.EMBEDDED.name()); 
     469                } 
     470 
     471                MasterPersister.persist(enumRef, storage.child("dataType"), 
     472                                options, PersistenceUtil.getStorageR3Schema(ResourceDataPersistType.class)); 
     473 
     474                if (ResourceDataPersistType.EMBEDDED == enumRef.get()) { 
     475                        MasterPersister.persist(ref, storage.getParent().getParent().getParent().attribute( 
     476                        "_data").attribute(embeddedFileName), options, 
     477                        PersistenceUtil.getStorageR3Schema(RawBinData.class)); 
     478                        if (options.isSaveMode()) { 
     479                                storage.attribute("src").setTextContent("./_data/" + embeddedFileName); 
     480                        } 
     481                } else if (ResourceDataPersistType.CHUNKED == enumRef.get()) { 
     482                        if (options.isSaveMode()) { 
     483                                ChunkedDataHolder holder = (ChunkedDataHolder) ref.get(); 
     484                                ref.set(holder.getChunkedBinData()); 
     485                        } 
     486                         
     487                        MasterPersister.persist(ref, storage, options,  
     488                                        PersistenceUtil.getStorageR3Schema(ChunkedDataHolder.class)); 
     489                } else { 
     490                        if (options.isSaveMode()) { 
     491                                FileBinData fileData = (FileBinData) ref.get(); 
     492 
     493                                if (ResourceDataPersistType.LINKED_ABSOLUTE == enumRef.get()) { 
     494                                        storage.attribute("src").setTextContent(fileData.getFile().getPath()); 
     495                                } else { 
     496                                        String parent = options.get(PersistenceUtil.LOCATION); 
     497 
     498                                        String source = ResourceFilesUtil.getSaveableLocation( 
     499                                                        parent, fileData.getFile()); 
     500                                        ResourceFilesUtil.saveLoadableResource(parent, 
     501                                                        source, fileData.getFile()); 
     502 
     503                                        storage.attribute("src").setTextContent(source); 
     504                                } 
     505                        } else { 
     506                                assert options.isLoadMode(); 
     507 
     508                                File sourceFile = null; 
     509                                String path = storage.attribute("src").getTextContent(); 
     510 
     511                                if (ResourceDataPersistType.LINKED_RELATIVE == enumRef.get()) { 
     512                                        String parent = options.get(PersistenceUtil.LOCATION); 
     513 
     514                                        String source = ResourceFilesUtil.getLoadableLocation( 
     515                                                        parent, path); 
     516                                        sourceFile = new File(ResourceFilesUtil.getValidPath(source)); 
     517                                } else { 
     518                                        assert ResourceDataPersistType.LINKED_ABSOLUTE == enumRef.get(); 
     519 
     520                                        sourceFile = new File(path); 
     521                                } 
     522 
     523                                ref.set(FileBinData.create(sourceFile, 
     524                                                ResourceDataPersistType.LINKED_ABSOLUTE == enumRef.get())); 
     525                        } 
     526                } 
     527        } 
     528 
     529} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/exports/ResourceExportManagerTest.java

     
    1313import javax.swing.filechooser.FileFilter; 
    1414 
    1515import org.junit.Test; 
     16import org.sophie2.base.config.BaseConfigModule; 
    1617import org.sophie2.base.media.BaseMediaModule; 
    1718import org.sophie2.base.model.resources.r4.BaseModelResourcesR4Module; 
    1819import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    1920import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
     21import org.sophie2.base.persistence.BasePersistenceModule; 
    2022import org.sophie2.base.skins.BaseSkinsModule; 
    2123import org.sophie2.base.visual.BaseVisualModule; 
    2224import org.sophie2.core.modularity.CoreModularityModule; 
     
    4143        protected List<Class<? extends SophieModule>> fillDependencies() { 
    4244                return Arrays.asList( 
    4345                                CoreModularityModule.class, 
     46                                BasePersistenceModule.class, 
     47                                BaseConfigModule.class, 
    4448                                BaseModelResourcesR4Module.class, 
    4549                                BaseSkinsModule.class, BaseVisualModule.class, 
    4650                                BaseMediaModule.class, MainMediaNatlibModule.class, 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/ChangeImageBackgroundAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.model.book.BackgroundType; 
     4import org.sophie2.base.model.book.interfaces.StyledElement; 
     5import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     6import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     7import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 
     8import org.sophie2.base.skins.Message; 
     9 
     10/** 
     11 * {@link AutoAction} for changes the background of an element to an image. 
     12 *  
     13 * @author tanya, deni 
     14 */ 
     15public class ChangeImageBackgroundAction extends AutoAction { 
     16         
     17        private final ResourceRefR4 elementToImageRef; 
     18 
     19        /** 
     20         * Creates the action with the needed relative reference from the element to the image. 
     21         *  
     22         * @param description  
     23         *                      Description of the action.  
     24         * @param significant  
     25         *                      Significance of the action.  
     26         * @param elementToImageRef 
     27         *                      The reference from the element (for which the background will be changed) 
     28         *                      to the image. 
     29         */ 
     30        public ChangeImageBackgroundAction(Message description, 
     31                        boolean significant, ResourceRefR4 elementToImageRef) { 
     32                super(description, significant); 
     33                 
     34                this.elementToImageRef = elementToImageRef; 
     35        } 
     36 
     37        @Override 
     38        public void performAuto() { 
     39                ResourceChanger changer = getChanger(); 
     40 
     41                changer.setRaw(StyledElement.KEY_BACKGROUND__IMAGE, this.elementToImageRef); 
     42                changer.setRaw(StyledElement.KEY_BACKGROUND__TYPE, BackgroundType.IMAGE); 
     43        } 
     44} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/actions/InsertTextFrameAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.commons.util.ImmList; 
     4import org.sophie2.base.commons.util.position.ImmPoint; 
     5import org.sophie2.base.model.book.frame.FrameR4; 
     6import org.sophie2.base.model.book.timelines.ActivationChannel; 
     7import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     8import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     9import org.sophie2.base.skins.Message; 
     10import org.sophie2.main.func.resources.dummy.ColdTextImportManager; 
     11 
     12/** 
     13 * {@link AutoAction} for inserting test frame with text. 
     14 *  
     15 * @author meddle 
     16 */ 
     17public class InsertTextFrameAction extends AutoAction { 
     18         
     19        private final ColdTextImportManager manager; 
     20        private final ResourceRefR4 frameRef; 
     21        private final ResourceRefR4 parentRef; 
     22        private final ImmList<ActivationChannel> elements; 
     23        private final ResourceRefR4 coldRef; 
     24 
     25        /** 
     26         * Creates the action with all needed information to insert the frame. 
     27         *  
     28         * @param description  
     29         *                      Description of the action.  
     30         * @param significant  
     31         *                      Significance of the action. 
     32         * @param manager 
     33         *                      The import manager to insert the frame. 
     34         * @param frameRef 
     35         *                      The reference to the frame. 
     36         * @param parentRef 
     37         *                      The parent of the frame. 
     38         * @param elements 
     39         *                      The current elements of the parent element. 
     40         * @param coldRef 
     41         *                      The reference to the main resource of the frame to insert 
     42         */ 
     43        public InsertTextFrameAction(Message description, boolean significant, 
     44                        ColdTextImportManager manager, ResourceRefR4 frameRef, 
     45                        ResourceRefR4 parentRef, ImmList<ActivationChannel> elements, 
     46                        ResourceRefR4 coldRef) { 
     47                super(description, significant); 
     48                 
     49                this.manager = manager; 
     50                this.frameRef = frameRef; 
     51                this.parentRef = parentRef; 
     52                this.elements = elements; 
     53                this.coldRef = coldRef; 
     54        } 
     55 
     56        @Override 
     57        public void performAuto() { 
     58                this.manager.insertFrame(getChanger().getSub(this.parentRef), 
     59                                this.parentRef, this.frameRef, this.coldRef, 
     60                                "Bau", this.elements, 
     61                                ImmPoint.ZERO, 
     62                                FrameR4.DEFAULT_FRAME_SIZE); 
     63        } 
     64} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/actions/CreateColdTextAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     4import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     5import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 
     6import org.sophie2.base.skins.Message; 
     7import org.sophie2.main.func.resources.dummy.ColdTextResource; 
     8import org.sophie2.main.func.resources.dummy.ColdTextResourceHelper; 
     9 
     10 
     11/** 
     12 * {@link AutoAction} for creating the {@link ColdTextResource}. 
     13 *  
     14 * @author meddle 
     15 */ 
     16public class CreateColdTextAction extends AutoAction { 
     17         
     18        private final String text; 
     19        private final ResourceRefR4 coldRef; 
     20 
     21        /** 
     22         * Creates the action with the location of the new resource and the text 
     23         * contained by it. 
     24         *  
     25         * @param description  
     26         *                      Description of the action.  
     27         * @param significant  
     28         *                      Significance of the action. 
     29         * @param text 
     30         *                      The text as string for the new resource. 
     31         * @param coldRef 
     32         *                      The reference to the place the resource will be created. 
     33         */ 
     34        public CreateColdTextAction(Message description, boolean significant, 
     35                        String text, ResourceRefR4 coldRef) { 
     36                super(description, significant); 
     37                 
     38                this.text = text; 
     39                this.coldRef = coldRef; 
     40        } 
     41 
     42        @Override 
     43        public void performAuto() { 
     44                ResourceChanger changer = getChanger(); 
     45                 
     46                ColdTextResourceHelper.createColdText(changer, this.coldRef, this.text); 
     47        } 
     48} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/SophiePackageFormatTest.java

     
    1 package org.sophie2.main.func.resources; 
    2  
    3 import java.io.File; 
    4 import java.net.URL; 
    5 import java.util.Collection; 
    6 import java.util.Collections; 
    7 import java.util.List; 
    8  
    9 import org.junit.After; 
    10 import org.junit.Before; 
    11 import org.junit.Test; 
    12 import org.sophie2.base.commons.util.bindata.BinData; 
    13 import org.sophie2.base.commons.util.bindata.RawBinData; 
    14 import org.sophie2.base.model.book.BaseModelBookModule; 
    15 import org.sophie2.base.model.book.BookH; 
    16 import org.sophie2.base.model.book.resource.r4.BookR4; 
    17 import org.sophie2.base.model.book.testing.ModelTestBase; 
    18 import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    19 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
    20 import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 
    21 import org.sophie2.base.model.resources.r4.keys.Key; 
    22 import org.sophie2.base.model.resources.r4.keys.RootKey; 
    23 import org.sophie2.base.model.resources.r4.model.ResourceModel; 
    24 import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    25 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
    26 import org.sophie2.base.persistence.BasePersistenceModule; 
    27 import org.sophie2.core.logging.LogLevel; 
    28 import org.sophie2.core.logging.SophieLog; 
    29 import org.sophie2.core.modularity.CoreModularityModule; 
    30 import org.sophie2.core.modularity.FileEntryManager; 
    31 import org.sophie2.core.modularity.SophieModule; 
    32 import org.sophie2.main.func.resources.exports.SophiePackageExportManager; 
    33 import org.sophie2.main.func.resources.imports.SophiePackageImportManager; 
    34  
    35 /** 
    36  * Tests exporting resources to package format and importing 
    37  * them from it. 
    38  *  
    39  * @author meddle 
    40  */ 
    41 public class SophiePackageFormatTest extends ModelTestBase { 
    42  
    43         private static final String TEST_BOOK_PATH = "testBook.book.s2"; 
    44         private static final String EXPORT_OUTPUT_PATH = "exported." +  
    45         SophiePackageExportManager.PACKAGES_EXTENSION; 
    46  
    47         private BookH testBook = null; 
    48         private SophiePackageExportManager exportManager = null; 
    49         private SophiePackageImportManager importManager = null;  
    50  
    51         private File exportOtputFile = null; 
    52  
    53         @Override 
    54         protected List<Class<? extends SophieModule>> fillDependencies() { 
    55                 List<Class<? extends SophieModule>> modules = super.fillDependencies();  
    56  
    57                 modules.add(CoreModularityModule.class); 
    58                 modules.add(BasePersistenceModule.class); 
    59                 modules.add(BaseModelBookModule.class); 
    60                 modules.add(MainFuncResourcesModule.class); 
    61  
    62                 return modules; 
    63         } 
    64  
    65         @Override 
    66         @Before 
    67         protected void setUp() throws Exception { 
    68                 super.setUp(); 
    69  
    70                 FileEntryManager entryManager = FileEntryManager.get(); 
    71                 URL testBookUrl = entryManager.getReadableFileEntry(TEST_BOOK_PATH); 
    72                 assertNotNull(testBookUrl); 
    73  
    74                 File testBookFile = new File(testBookUrl.getFile()); 
    75  
    76                 ResourceRefR4 testBookRef = ResourceRefR4.make(testBookFile); 
    77                 ResourceAccess access = getAppLocator().open(testBookRef, null); 
    78                 assertEquals(BookR4.KIND, ResourceR4.KEY_KIND.get(access)); 
    79  
    80                 this.testBook = ResourceH.getHelper(access, BookH.class); 
    81  
    82                 this.exportManager = new SophiePackageExportManager(); 
    83                 this.exportManager.initLocator(getAppLocator()); 
    84  
    85                 this.importManager = new SophiePackageImportManager(); 
    86                 this.importManager.initLocator(getAppLocator()); 
    87  
    88                 this.exportOtputFile = entryManager.getWritableFileEntry(EXPORT_OUTPUT_PATH); 
    89  
    90                 SophieLog.setMinLevel("org.sophie2.base.model.resources.r4.model", LogLevel.DEBUG); 
    91         } 
    92  
    93         @Override 
    94         @After 
    95         protected void tearDown() throws Exception { 
    96                 this.exportOtputFile = null; 
    97                 this.exportManager = null; 
    98                 this.testBook = null; 
    99  
    100                 super.tearDown(); 
    101         } 
    102  
    103         /** 
    104          * Tests exporting a resource to package format and 
    105          * than importing it. 
    106          *  
    107          * @throws Exception 
    108          */ 
    109         @Test 
    110         public void testExportImportResource() throws Exception { 
    111                 Boolean exported = this.exportManager.export( 
    112                                 this.testBook.getAccess(), this.exportOtputFile); 
    113  
    114                 assertTrue(exported); 
    115  
    116                 ResourceModel originalModel = this.testBook.getAccess().getHead().getModel(); 
    117                 ResourceModel exportedModel = this.importManager.getResourceData( 
    118                                 this.exportOtputFile, 
    119                                 null, Collections.EMPTY_MAP); 
    120  
    121                 assertNotNull(exportedModel); 
    122                 exportedModel.debugPrint(); 
    123                 originalModel.debugPrint(); 
    124  
    125                 // The models will be not equal because the imported resource is in the 
    126                 // tmp dir => its large resources :). 
    127  
    128                 // So some light checks: 
    129                 compareModels(originalModel, exportedModel); 
    130         } 
    131  
    132         private void compareModels(ResourceModel originalModel, 
    133                         ResourceModel exportedModel) { 
    134                 if (originalModel == null) { 
    135                         assertNull(exportedModel); 
    136                         return; 
    137                 } 
    138                  
    139                 Collection<Key<?>> keys = ResourceR4.getKnownKeys(BookR4.class).values(); 
    140                 for (Key<?> key : keys) { 
    141                         if (BinData.class.isAssignableFrom(key.getValueClass())) { 
    142                                 BinData exportedData = (BinData) exportedModel.getRaw(key); 
    143                                 BinData originalData = (BinData) originalModel.getRaw(key); 
    144  
    145                                 RawBinData derExportedData = new RawBinData(exportedData.getBytes()); 
    146                                 RawBinData derOriginalData = new RawBinData(originalData.getBytes()); 
    147                                 assertEquals(derExportedData, derOriginalData); 
    148                         } else { 
    149                                 Object exportedlVal = exportedModel.getRaw(key); 
    150                                 Object originalVal = originalModel.getRaw(key); 
    151                                 if (originalVal == null) { 
    152                                         assertNull(exportedlVal); 
    153                                 } else { 
    154                                         assertEquals(exportedlVal, originalVal); 
    155                                 } 
    156                         } 
    157                 }  
    158  
    159                 SubEntryNames children = ResourceR4.KEY_CHILDREN.get(this.testBook.getAccess()); 
    160                 for (String childName : children) { 
    161                         ResourceRefR4 childRef = ResourceRefR4.makeChild(childName); 
    162                         Key<?> childKey = RootKey.fromRef(childRef); 
    163                         compareModels(exportedModel.getSubModel(childKey), 
    164                                         originalModel.getSubModel(childKey)); 
    165                 } 
    166         } 
    167  
    168 } 
     1package org.sophie2.main.func.resources; 
     2 
     3import java.io.File; 
     4import java.net.URL; 
     5import java.util.Arrays; 
     6import java.util.Collection; 
     7import java.util.Collections; 
     8import java.util.List; 
     9 
     10import org.junit.After; 
     11import org.junit.Before; 
     12import org.junit.Test; 
     13import org.sophie2.base.commons.util.bindata.BinData; 
     14import org.sophie2.base.commons.util.bindata.RawBinData; 
     15import org.sophie2.base.config.BaseConfigModule; 
     16import org.sophie2.base.model.book.BaseModelBookModule; 
     17import org.sophie2.base.model.book.BookH; 
     18import org.sophie2.base.model.book.resource.r4.BookR4; 
     19import org.sophie2.base.model.book.testing.ModelTestBase; 
     20import org.sophie2.base.model.resources.r4.BaseModelResourcesR4Module; 
     21import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     22import org.sophie2.base.model.resources.r4.access.ResourceAccess; 
     23import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 
     24import org.sophie2.base.model.resources.r4.keys.Key; 
     25import org.sophie2.base.model.resources.r4.keys.RootKey; 
     26import org.sophie2.base.model.resources.r4.model.ResourceModel; 
     27import org.sophie2.base.model.resources.r4.resources.ResourceH; 
     28import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
     29import org.sophie2.base.persistence.BasePersistenceModule; 
     30import org.sophie2.core.logging.LogLevel; 
     31import org.sophie2.core.logging.SophieLog; 
     32import org.sophie2.core.modularity.CoreModularityModule; 
     33import org.sophie2.core.modularity.FileEntryManager; 
     34import org.sophie2.core.modularity.SophieModule; 
     35import org.sophie2.main.func.resources.exports.SophiePackageExportManager; 
     36import org.sophie2.main.func.resources.imports.SophiePackageImportManager; 
     37 
     38/** 
     39 * Tests exporting resources to package format and importing 
     40 * them from it. 
     41 *  
     42 * @author meddle 
     43 */ 
     44public class SophiePackageFormatTest extends ModelTestBase { 
     45 
     46        private static final String TEST_BOOK_PATH = "testBook.book.s2"; 
     47        private static final String EXPORT_OUTPUT_PATH = "exported." +  
     48        SophiePackageExportManager.PACKAGES_EXTENSION; 
     49 
     50        private BookH testBook = null; 
     51        private SophiePackageExportManager exportManager = null; 
     52        private SophiePackageImportManager importManager = null;  
     53 
     54        private File exportOtputFile = null; 
     55 
     56        @SuppressWarnings("unchecked") 
     57        @Override 
     58        protected List<Class<? extends SophieModule>> fillDependencies() { 
     59                return Arrays.asList( 
     60                                CoreModularityModule.class, 
     61                                BaseConfigModule.class, 
     62                                BasePersistenceModule.class, 
     63                                BaseModelResourcesR4Module.class, 
     64                                BaseModelBookModule.class, 
     65                                MainFuncResourcesModule.class);  
     66                } 
     67 
     68        @Override 
     69        @Before 
     70        protected void setUp() throws Exception { 
     71                super.setUp(); 
     72 
     73                FileEntryManager entryManager = FileEntryManager.get(); 
     74                URL testBookUrl = entryManager.getReadableFileEntry(TEST_BOOK_PATH); 
     75                assertNotNull(testBookUrl); 
     76 
     77                File testBookFile = new File(testBookUrl.getFile()); 
     78 
     79                ResourceRefR4 testBookRef = ResourceRefR4.make(testBookFile); 
     80                ResourceAccess access = getAppLocator().open(testBookRef, null); 
     81                assertEquals(BookR4.KIND, ResourceR4.KEY_KIND.get(access)); 
     82 
     83                this.testBook = ResourceH.getHelper(access, BookH.class); 
     84 
     85                this.exportManager = new SophiePackageExportManager(); 
     86                this.exportManager.initLocator(getAppLocator()); 
     87 
     88                this.importManager = new SophiePackageImportManager(); 
     89                this.importManager.initLocator(getAppLocator()); 
     90 
     91                this.exportOtputFile = entryManager.getWritableFileEntry(EXPORT_OUTPUT_PATH); 
     92 
     93                SophieLog.setMinLevel("org.sophie2.base.model.resources.r4.model", LogLevel.DEBUG); 
     94        } 
     95 
     96        @Override 
     97        @After 
     98        protected void tearDown() throws Exception { 
     99                this.exportOtputFile = null; 
     100                this.exportManager = null; 
     101                this.testBook = null; 
     102 
     103                super.tearDown(); 
     104        } 
     105 
     106        /** 
     107         * Tests exporting a resource to package format and 
     108         * than importing it. 
     109         *  
     110         * @throws Exception 
     111         */ 
     112        @Test 
     113        public void testExportImportResource() throws Exception { 
     114                Boolean exported = this.exportManager.export( 
     115                                this.testBook.getAccess(), this.exportOtputFile); 
     116 
     117                assertTrue(exported); 
     118 
     119                ResourceModel originalModel = this.testBook.getAccess().getHead().getModel(); 
     120                ResourceModel exportedModel = this.importManager.getResourceData( 
     121                                this.exportOtputFile, 
     122                                null, Collections.EMPTY_MAP); 
     123 
     124                assertNotNull(exportedModel); 
     125                exportedModel.debugPrint(); 
     126                originalModel.debugPrint(); 
     127 
     128                // The models will be not equal because the imported resource is in the 
     129                // tmp dir => its large resources :). 
     130 
     131                // So some light checks: 
     132                compareModels(originalModel, exportedModel); 
     133        } 
     134 
     135        private void compareModels(ResourceModel originalModel, 
     136                        ResourceModel exportedModel) { 
     137                if (originalModel == null) { 
     138                        assertNull(exportedModel); 
     139                        return; 
     140                } 
     141                 
     142                Collection<Key<?>> keys = ResourceR4.getKnownKeys(BookR4.class).values(); 
     143                for (Key<?> key : keys) { 
     144                        if (BinData.class.isAssignableFrom(key.getValueClass())) { 
     145                                BinData exportedData = (BinData) exportedModel.getRaw(key); 
     146                                BinData originalData = (BinData) originalModel.getRaw(key); 
     147 
     148                                RawBinData derExportedData = new RawBinData(exportedData.getBytes()); 
     149                                RawBinData derOriginalData = new RawBinData(originalData.getBytes()); 
     150                                assertEquals(derExportedData, derOriginalData); 
     151                        } else { 
     152                                Object exportedlVal = exportedModel.getRaw(key); 
     153                                Object originalVal = originalModel.getRaw(key); 
     154                                if (originalVal == null) { 
     155                                        assertNull(exportedlVal); 
     156                                } else { 
     157                                        assertEquals(exportedlVal, originalVal); 
     158                                } 
     159                        } 
     160                }  
     161 
     162                SubEntryNames children = ResourceR4.KEY_CHILDREN.get(this.testBook.getAccess()); 
     163                for (String childName : children) { 
     164                        ResourceRefR4 childRef = ResourceRefR4.makeChild(childName); 
     165                        Key<?> childKey = RootKey.fromRef(childRef); 
     166                        compareModels(exportedModel.getSubModel(childKey), 
     167                                        originalModel.getSubModel(childKey)); 
     168                } 
     169        } 
     170 
     171} 
  • modules/org.sophie2.main.func.resources/src/test/java/org/sophie2/main/func/resources/dummy/ColdTextResourceHelper.java

     
    77import org.sophie2.base.model.resources.r4.resources.ResourceH; 
    88import org.sophie2.base.model.resources.r4.resources.ResourceR4; 
    99import org.sophie2.base.skins.Message; 
     10import org.sophie2.main.func.resources.actions.CreateColdTextAction; 
    1011 
    1112/** 
    1213 * The helper of our cold text... 
     
    8283                final ResourceRefR4 coldRef =  
    8384                        ResourceRefR4.generateRandomSub(ColdTextResource.DEFAULT_TITLE); 
    8485                 
    85                 new AutoAction(Message.create(CREATING_COLD_TEXT), true) { 
    86                         @Override 
    87                         public void performAuto() { 
    88                                 ColdTextResourceHelper.createColdText( 
    89                                                 getChanger(), coldRef, text); 
    90                         } 
    91                 }.register(bookAccess); 
     86                Message description = Message.create(CREATING_COLD_TEXT); 
     87                AutoAction action = new CreateColdTextAction(description, true, text, coldRef); 
     88                action.register(bookAccess); 
    9289                 
    9390                return bookAccess.open(coldRef, null); 
    9491        } 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/RemoveTemplateAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.model.resources.r4.ResourceRefList; 
     4import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     5import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     6import org.sophie2.base.model.resources.r4.keys.Key; 
     7import org.sophie2.base.skins.Message; 
     8 
     9/** 
     10 * {@link AutoAction} for removing a template. 
     11 *  
     12 * @author diana 
     13 */ 
     14public class RemoveTemplateAction extends AutoAction { 
     15         
     16        private final ResourceRefList templates; 
     17        private final Key<ResourceRefList> key; 
     18        private final ResourceRefR4 ref; 
     19 
     20        /** 
     21         * Creates the action with all the needed data for template removal. 
     22         *  
     23         * @param description  
     24         *                      Description of the action.  
     25         * @param significant  
     26         *                      Significance of the action. 
     27         * @param templates 
     28         *                      The current list with the templates. 
     29         * @param key 
     30         *                      The key containing the templates. 
     31         * @param ref 
     32         *                      The reference to the template to remove. 
     33         */ 
     34        public RemoveTemplateAction(Message description, boolean significant, 
     35                        ResourceRefList templates, Key<ResourceRefList> key, 
     36                        ResourceRefR4 ref) { 
     37                super(description, significant); 
     38                 
     39                this.templates = templates; 
     40                this.key = key; 
     41                this.ref = ref; 
     42        } 
     43 
     44        @Override 
     45        public void performAuto() { 
     46                getChanger().removeResource(this.ref); 
     47                getChanger().setRaw(this.key, this.templates.remove(this.ref)); 
     48        } 
     49} 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/InsertFrameAction.java

     
     1package org.sophie2.main.func.resources.actions; 
     2 
     3import org.sophie2.base.commons.util.ImmList; 
     4import org.sophie2.base.commons.util.position.ImmPoint; 
     5import org.sophie2.base.commons.util.position.ImmSize; 
     6import org.sophie2.base.model.book.timelines.ActivationChannel; 
     7import org.sophie2.base.model.resources.r4.ResourceRefR4; 
     8import org.sophie2.base.model.resources.r4.changes.AutoAction; 
     9import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 
     10import org.sophie2.base.skins.Message; 
     11import org.sophie2.main.func.resources.imports.ResourceImportInfo; 
     12import org.sophie2.main.func.resources.imports.ResourceImportManager; 
     13 
     14/** 
     15 * {@link AutoAction} for inserting a frame for given resource. 
     16 * It makes resource if the resource is not created and inserts frame for it. 
     17 *  
     18 * @author meddle 
     19 * 
     20 * @param <D> 
     21 *                              The type of the resource data to insert frame for. 
     22 */ 
     23public class InsertFrameAction<D> extends AutoAction { 
     24         
     25        private final ResourceImportInfo<D> importInfo; 
     26        private final ResourceRefR4 frameRef; 
     27        private final ImmPoint pos; 
     28        private final ImmSize frameSize; 
     29        private final ImmList<ActivationChannel> elements; 
     30        private final ResourceRefR4 parentRef; 
     31        private final ResourceImportManager<D> importManager; 
     32        private final boolean linked; 
     33        private final ResourceRefR4 resourceRef; 
     34        private final String frameTitle; 
     35 
     36        /** 
     37         * Creates the action with all needed data to insert a frame for a resource. 
     38         *  
     39         * @param description  
     40         *                      Description of the action.  
     41         * @param significant  
     42         *                      Significance of the action.  
     43         * @param importInfo 
     44         *                      The {@link ResourceImportInfo} needed for the resource contained 
     45         *                      in the frame. 
     46         * @param frameRef 
     47         *                      The {@link ResourceRefR4} for the new frame. 
     48         * @param pos 
     49         *                      The position of the new frame. 
     50         * @param frameSize 
     51         *                      The size of the new frame. 
     52         * @param elements 
     53         *                      The current sub-elements of the parent element of the new frame. 
     54         * @param parentRef 
     55         *                      The {@link ResourceRefR4} pointing to the parent of the new frame. 
     56         * @param importManager 
     57         *                      The {@link ResourceImportManager} responsible for creating resource 
     58         *                      for the frame and creating the frame. 
     59         * @param linked 
     60         *                      If the resource in the frame is linked (i.e. already created). 
     61         * @param resourceRef 
     62         *                      The reference to the resource the new frame shows. 
     63         * @param frameTitle 
     64         *                      The title of the new frame. 
     65         */ 
     66        public InsertFrameAction(Message description, boolean significant, 
     67                        ResourceImportInfo<D> importInfo, ResourceRefR4 frameRef, 
     68                        ImmPoint pos, ImmSize frameSize, 
     69                        ImmList<ActivationChannel> elements, ResourceRefR4 parentRef, 
     70                        ResourceImportManager<D> importManager, boolean linked, 
     71                        ResourceRefR4 resourceRef, String frameTitle) { 
     72                super(description, significant); 
     73                 
     74                this.importInfo = importInfo; 
     75                this.frameRef = frameRef; 
     76                this.pos = pos; 
     77                this.frameSize = frameSize; 
     78                this.elements = elements; 
     79                this.parentRef = parentRef; 
     80                this.importManager = importManager; 
     81                this.linked = linked; 
     82                this.resourceRef = resourceRef; 
     83                this.frameTitle = frameTitle; 
     84        } 
     85 
     86        @Override 
     87        public void performAuto() { 
     88                ResourceChanger changer = getChanger(); 
     89                if (!this.linked) { 
     90                        this.importManager.makeResource(changer, this.resourceRef, this.importInfo); 
     91                } 
     92 
     93                this.importManager.insertFrame(changer.getSub(this.parentRef), 
     94                                this.parentRef, this.frameRef, this.resourceRef, this.frameTitle, 
     95                                this.elements, this.pos, this.frameSize); 
     96 
     97        } 
     98} 
  • modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/logic/ChangeBackgroundHandler.java

     
    33import org.sophie2.base.dnd.DndTransferable; 
    44import org.sophie2.base.dnd.DropHandler; 
    55import org.sophie2.base.dnd.dnddata.ImageData; 
    6 import org.sophie2.base.model.book.BackgroundType; 
    76import org.sophie2.base.model.book.BookH; 
    8 import org.sophie2.base.model.book.interfaces.StyledElement; 
    97import org.sophie2.base.model.resources.r4.ResourceRefR4; 
    108import org.sophie2.base.model.resources.r4.changes.AutoAction; 
    11 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 
    129import org.sophie2.base.skins.Message; 
    1310import org.sophie2.main.app.commons.element.ElementDropHandler; 
    1411import org.sophie2.main.app.commons.element.ElementView; 
    1512import org.sophie2.main.dnd.dnddata.ResourceRefData; 
     13import org.sophie2.main.func.resources.actions.ChangeImageBackgroundAction; 
    1614import org.sophie2.main.func.resources.imports.ResourceImportUtil; 
    1715 
    1816/** 
     
    6967                final ResourceRefR4 elementToImageRef =  
    7068                        ResourceRefR4.getRelativeRef(absElementRef, absImageRef); 
    7169         
    72                 new AutoAction(Message.create(SET_IMAGE_BG), true) { 
    73  
    74                         @Override 
    75                         public void performAuto() { 
    76                                 ResourceChanger changer = getChanger(); 
    77  
    78                                 changer.setRaw(StyledElement.KEY_BACKGROUND__IMAGE, elementToImageRef); 
    79                                 changer.setRaw(StyledElement.KEY_BACKGROUND__TYPE, BackgroundType.IMAGE); 
    80                         } 
    81                 }.register(getView().getAccess()); 
     70                Message description = Message.create(SET_IMAGE_BG); 
     71                AutoAction action = new ChangeImageBackgroundAction(description, true, elementToImageRef); 
     72                action.register(getView().getAccess()); 
    8273        } 
    8374}