Ticket #2427: actions2.patch
File actions2.patch, 134.1 KB (added by meddle, 15 years ago) |
---|
-
modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/RemoveResourceAction.java
### Eclipse Workspace Patch 1.0 #P sophie
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.model.resources.r4.ResourceRefR4; 4 import org.sophie2.base.model.resources.r4.changes.AutoAction; 5 import org.sophie2.base.skins.Message; 6 7 /** 8 * {@link AutoAction} for deleting a resource. 9 * 10 * @author diana 11 */ 12 public 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
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.commons.util.NaiveImmList; 4 import org.sophie2.base.model.resources.r4.ResourceRefR4; 5 import org.sophie2.base.model.resources.r4.changes.AutoAction; 6 import org.sophie2.base.model.resources.r4.keys.TemplatedKey; 7 import org.sophie2.base.skins.Message; 8 import org.sophie2.main.app.commons.util.TemplateUtil; 9 10 /** 11 * {@link AutoAction} for applying a template to a resource. 12 * 13 * @author deni 14 */ 15 public 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
8 8 9 9 import org.junit.Before; 10 10 import org.junit.Test; 11 import org.sophie2.base.bound.BoundModule; 11 12 import org.sophie2.base.commons.BaseCommonsModule; 12 13 import org.sophie2.base.commons.util.position.ImmPoint; 14 import org.sophie2.base.config.BaseConfigModule; 13 15 import org.sophie2.base.dialogs.BaseDialogsModule; 14 16 import org.sophie2.base.dialogs.TestingDialogManager; 15 17 import org.sophie2.base.dnd.DndData; … … 28 30 import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 29 31 import org.sophie2.base.model.resources.r4.resources.ResourceH; 30 32 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 33 import org.sophie2.base.persistence.BasePersistenceModule; 31 34 import org.sophie2.base.skins.BaseSkinsModule; 32 35 import org.sophie2.base.skins.Message; 33 36 import org.sophie2.base.visual.BaseVisualModule; … … 41 44 import org.sophie2.main.dialogs.input.file.FileDialogInput; 42 45 import org.sophie2.main.dialogs.input.file.FileFilterInfo; 43 46 import org.sophie2.main.func.file.FileFunctionalityModule; 47 import org.sophie2.main.func.resources.actions.CreateColdTextAction; 44 48 import org.sophie2.main.func.resources.dummy.ColdTextData; 45 49 import org.sophie2.main.func.resources.dummy.ColdTextFrame; 46 50 import org.sophie2.main.func.resources.dummy.ColdTextImportManager; … … 117 121 protected List<Class<? extends SophieModule>> fillDependencies() { 118 122 return Arrays.asList(BaseModelResourcesR4Module.class, 119 123 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, 124 129 ColdTextModule.class); 125 130 } 126 131 … … 275 280 ResourceRefR4.generateRandomSub(ColdTextResource.DEFAULT_TITLE); 276 281 final String text = "My text"; 277 282 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); 286 286 287 287 // text and page: 288 288 assertEquals(2, book.getChildren().size()); -
modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/SetFrameResourceAction.java
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.model.book.interfaces.ResourceFrame; 4 import org.sophie2.base.model.resources.r4.ResourceRefR4; 5 import org.sophie2.base.model.resources.r4.changes.AutoAction; 6 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 7 import org.sophie2.base.skins.Message; 8 9 /** 10 * {@link AutoAction} for changing the main resource of a frame. 11 * 12 * @author deni 13 */ 14 public 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 } 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.keys.TemplatedKey; 34 import org.sophie2.base.model.resources.r4.model.ResourceModel; 35 import org.sophie2.base.model.resources.r4.resources.ResourceH; 36 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 37 import org.sophie2.base.skins.Message; 38 import org.sophie2.core.logging.SophieLog; 39 import org.sophie2.main.dialogs.input.DialogUtils; 40 import org.sophie2.main.dialogs.input.MessageDialogInput; 41 import org.sophie2.main.dialogs.input.MessageDialogInput.MessageType; 42 import org.sophie2.main.dialogs.input.file.FileDialogInput; 43 import org.sophie2.main.func.resources.actions.ApplyTemplateAction; 44 import org.sophie2.main.func.resources.actions.ImportResourceAction; 45 import org.sophie2.main.func.resources.actions.InsertFrameAction; 46 import 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 */ 54 public 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
3 3 import org.sophie2.base.dnd.DndTransferable; 4 4 import org.sophie2.base.dnd.DropHandler; 5 5 import org.sophie2.base.model.book.BookH; 6 import org.sophie2.base.model.book.interfaces.ResourceFrame;7 6 import org.sophie2.base.model.resources.r4.ResourceRefR4; 8 7 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 9 8 import org.sophie2.base.model.resources.r4.changes.AutoAction; … … 15 14 import org.sophie2.main.app.commons.element.ElementDropHandler; 16 15 import org.sophie2.main.app.commons.frame.FrameView; 17 16 import org.sophie2.main.dnd.dnddata.ResourceRefData; 17 import org.sophie2.main.func.resources.actions.SetFrameResourceAction; 18 18 import org.sophie2.main.func.resources.imports.ResourceImportProvider; 19 19 import org.sophie2.main.func.resources.imports.ResourceImportUtil; 20 20 import org.sophie2.main.func.resources.imports.SimpleResourceImportProvider; … … 88 88 LogicR3.fire(getView(), bdw, null, null, BookView.EventIds.DELETING_ELEMENT, 89 89 ResourceDeleteLogic.findElementView(bookToFrameRef, getView().getBookView())); 90 90 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); 99 94 } 100 95 } -
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 } 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.bound.BoundModule; 10 import org.sophie2.base.commons.BaseCommonsModule; 11 import org.sophie2.base.commons.structures.ImmTreeList; 12 import org.sophie2.base.commons.util.ImmList; 13 import org.sophie2.base.config.BaseConfigModule; 14 import org.sophie2.base.dialogs.BaseDialogsModule; 15 import org.sophie2.base.dialogs.TestingDialogManager; 16 import org.sophie2.base.media.BaseMediaModule; 17 import org.sophie2.base.model.book.BaseModelBookModule; 18 import org.sophie2.base.model.book.FrameH; 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.persistence.BasePersistenceModule; 32 import org.sophie2.base.skins.BaseSkinsModule; 33 import org.sophie2.base.skins.Message; 34 import org.sophie2.base.visual.BaseVisualModule; 35 import org.sophie2.core.modularity.FileEntryManager; 36 import org.sophie2.core.modularity.SophieModule; 37 import org.sophie2.main.app.commons.MainAppModule; 38 import org.sophie2.main.app.commons.testing.AppTestBase; 39 import org.sophie2.main.dialogs.input.MessageDialogInput; 40 import org.sophie2.main.dialogs.input.file.FileContainer; 41 import org.sophie2.main.dialogs.input.file.FileDialogInput; 42 import org.sophie2.main.dialogs.input.file.FileFilterInfo; 43 import org.sophie2.main.func.file.FileFunctionalityModule; 44 import org.sophie2.main.func.resources.actions.CreateColdTextAction; 45 import org.sophie2.main.func.resources.actions.InsertTextFrameAction; 46 import org.sophie2.main.func.resources.dummy.ColdTextImportManager; 47 import org.sophie2.main.func.resources.dummy.ColdTextModule; 48 import org.sophie2.main.func.resources.dummy.ColdTextResource; 49 import org.sophie2.main.func.resources.dummy.ColdTextResourceHelper; 50 import org.sophie2.main.media.natlib.MainMediaNatlibModule; 51 52 /** 53 * Test the common logic implemented in the {@link ResourceImportManager}. 54 * 55 * @author meddle 56 */ 57 public 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
24 24 import org.sophie2.main.app.commons.util.AppViewUtil; 25 25 import org.sophie2.main.dialogs.input.ConfirmDialogInput; 26 26 import org.sophie2.main.dialogs.input.DialogUtils; 27 import org.sophie2.main.func.resources.actions.RemoveResourceAction; 28 import org.sophie2.main.func.resources.actions.RemoveTemplateAction; 27 29 import org.sophie2.main.func.resources.view.ResourceDetailsPalette; 28 30 import org.sophie2.main.func.resources.view.ResourceDetailsPalette.DeleteResourceButton; 29 31 import org.sophie2.main.func.resources.view.ResourcesPalette.ResourceItem; … … 84 86 return true; 85 87 } 86 88 }; 87 89 88 90 /** 89 91 * Constant created for removing template. 90 92 * Constant created to be a parameter of a message of an {@link AutoAction}. … … 122 124 123 125 final ResourceRefR4 resourceRef = ResourceRefR4.getRelativeRef( 124 126 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); 130 131 131 }.register(bookAccess);132 133 132 return true; 134 133 } 135 134 … … 205 204 ResourceAccess bookAccess = bookView.getAccess(); 206 205 final ResourceRefList templates = key.get(bookAccess); 207 206 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); 216 210 217 211 return true; 218 212 } -
modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/ImportResourceAction.java
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.model.resources.r4.ResourceRefR4; 4 import org.sophie2.base.model.resources.r4.changes.AutoAction; 5 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 6 import org.sophie2.base.skins.Message; 7 import org.sophie2.main.func.resources.imports.ResourceImportInfo; 8 import 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 */ 18 public 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 } 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 * 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
13 13 import javax.swing.filechooser.FileFilter; 14 14 15 15 import org.junit.Test; 16 import org.sophie2.base.config.BaseConfigModule; 16 17 import org.sophie2.base.media.BaseMediaModule; 17 18 import org.sophie2.base.model.resources.r4.BaseModelResourcesR4Module; 18 19 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 19 20 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 21 import org.sophie2.base.persistence.BasePersistenceModule; 20 22 import org.sophie2.base.skins.BaseSkinsModule; 21 23 import org.sophie2.base.visual.BaseVisualModule; 22 24 import org.sophie2.core.modularity.CoreModularityModule; … … 41 43 protected List<Class<? extends SophieModule>> fillDependencies() { 42 44 return Arrays.asList( 43 45 CoreModularityModule.class, 46 BasePersistenceModule.class, 47 BaseConfigModule.class, 44 48 BaseModelResourcesR4Module.class, 45 49 BaseSkinsModule.class, BaseVisualModule.class, 46 50 BaseMediaModule.class, MainMediaNatlibModule.class, -
modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/ChangeImageBackgroundAction.java
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.model.book.BackgroundType; 4 import org.sophie2.base.model.book.interfaces.StyledElement; 5 import org.sophie2.base.model.resources.r4.ResourceRefR4; 6 import org.sophie2.base.model.resources.r4.changes.AutoAction; 7 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 8 import 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 */ 15 public 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
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.commons.util.ImmList; 4 import org.sophie2.base.commons.util.position.ImmPoint; 5 import org.sophie2.base.model.book.frame.FrameR4; 6 import org.sophie2.base.model.book.timelines.ActivationChannel; 7 import org.sophie2.base.model.resources.r4.ResourceRefR4; 8 import org.sophie2.base.model.resources.r4.changes.AutoAction; 9 import org.sophie2.base.skins.Message; 10 import org.sophie2.main.func.resources.dummy.ColdTextImportManager; 11 12 /** 13 * {@link AutoAction} for inserting test frame with text. 14 * 15 * @author meddle 16 */ 17 public 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
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.model.resources.r4.ResourceRefR4; 4 import org.sophie2.base.model.resources.r4.changes.AutoAction; 5 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 6 import org.sophie2.base.skins.Message; 7 import org.sophie2.main.func.resources.dummy.ColdTextResource; 8 import org.sophie2.main.func.resources.dummy.ColdTextResourceHelper; 9 10 11 /** 12 * {@link AutoAction} for creating the {@link ColdTextResource}. 13 * 14 * @author meddle 15 */ 16 public 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 } 1 package org.sophie2.main.func.resources; 2 3 import java.io.File; 4 import java.net.URL; 5 import java.util.Arrays; 6 import java.util.Collection; 7 import java.util.Collections; 8 import java.util.List; 9 10 import org.junit.After; 11 import org.junit.Before; 12 import org.junit.Test; 13 import org.sophie2.base.commons.util.bindata.BinData; 14 import org.sophie2.base.commons.util.bindata.RawBinData; 15 import org.sophie2.base.config.BaseConfigModule; 16 import org.sophie2.base.model.book.BaseModelBookModule; 17 import org.sophie2.base.model.book.BookH; 18 import org.sophie2.base.model.book.resource.r4.BookR4; 19 import org.sophie2.base.model.book.testing.ModelTestBase; 20 import org.sophie2.base.model.resources.r4.BaseModelResourcesR4Module; 21 import org.sophie2.base.model.resources.r4.ResourceRefR4; 22 import org.sophie2.base.model.resources.r4.access.ResourceAccess; 23 import org.sophie2.base.model.resources.r4.immutables.SubEntryNames; 24 import org.sophie2.base.model.resources.r4.keys.Key; 25 import org.sophie2.base.model.resources.r4.keys.RootKey; 26 import org.sophie2.base.model.resources.r4.model.ResourceModel; 27 import org.sophie2.base.model.resources.r4.resources.ResourceH; 28 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 29 import org.sophie2.base.persistence.BasePersistenceModule; 30 import org.sophie2.core.logging.LogLevel; 31 import org.sophie2.core.logging.SophieLog; 32 import org.sophie2.core.modularity.CoreModularityModule; 33 import org.sophie2.core.modularity.FileEntryManager; 34 import org.sophie2.core.modularity.SophieModule; 35 import org.sophie2.main.func.resources.exports.SophiePackageExportManager; 36 import 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 */ 44 public 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
7 7 import org.sophie2.base.model.resources.r4.resources.ResourceH; 8 8 import org.sophie2.base.model.resources.r4.resources.ResourceR4; 9 9 import org.sophie2.base.skins.Message; 10 import org.sophie2.main.func.resources.actions.CreateColdTextAction; 10 11 11 12 /** 12 13 * The helper of our cold text... … … 82 83 final ResourceRefR4 coldRef = 83 84 ResourceRefR4.generateRandomSub(ColdTextResource.DEFAULT_TITLE); 84 85 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); 92 89 93 90 return bookAccess.open(coldRef, null); 94 91 } -
modules/org.sophie2.main.func.resources/src/main/java/org/sophie2/main/func/resources/actions/RemoveTemplateAction.java
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.model.resources.r4.ResourceRefList; 4 import org.sophie2.base.model.resources.r4.ResourceRefR4; 5 import org.sophie2.base.model.resources.r4.changes.AutoAction; 6 import org.sophie2.base.model.resources.r4.keys.Key; 7 import org.sophie2.base.skins.Message; 8 9 /** 10 * {@link AutoAction} for removing a template. 11 * 12 * @author diana 13 */ 14 public 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
1 package org.sophie2.main.func.resources.actions; 2 3 import org.sophie2.base.commons.util.ImmList; 4 import org.sophie2.base.commons.util.position.ImmPoint; 5 import org.sophie2.base.commons.util.position.ImmSize; 6 import org.sophie2.base.model.book.timelines.ActivationChannel; 7 import org.sophie2.base.model.resources.r4.ResourceRefR4; 8 import org.sophie2.base.model.resources.r4.changes.AutoAction; 9 import org.sophie2.base.model.resources.r4.changes.ResourceChanger; 10 import org.sophie2.base.skins.Message; 11 import org.sophie2.main.func.resources.imports.ResourceImportInfo; 12 import 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 */ 23 public 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
3 3 import org.sophie2.base.dnd.DndTransferable; 4 4 import org.sophie2.base.dnd.DropHandler; 5 5 import org.sophie2.base.dnd.dnddata.ImageData; 6 import org.sophie2.base.model.book.BackgroundType;7 6 import org.sophie2.base.model.book.BookH; 8 import org.sophie2.base.model.book.interfaces.StyledElement;9 7 import org.sophie2.base.model.resources.r4.ResourceRefR4; 10 8 import org.sophie2.base.model.resources.r4.changes.AutoAction; 11 import org.sophie2.base.model.resources.r4.changes.ResourceChanger;12 9 import org.sophie2.base.skins.Message; 13 10 import org.sophie2.main.app.commons.element.ElementDropHandler; 14 11 import org.sophie2.main.app.commons.element.ElementView; 15 12 import org.sophie2.main.dnd.dnddata.ResourceRefData; 13 import org.sophie2.main.func.resources.actions.ChangeImageBackgroundAction; 16 14 import org.sophie2.main.func.resources.imports.ResourceImportUtil; 17 15 18 16 /** … … 69 67 final ResourceRefR4 elementToImageRef = 70 68 ResourceRefR4.getRelativeRef(absElementRef, absImageRef); 71 69 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()); 82 73 } 83 74 }