ArchiveMgr class

Started by Hervé, June 14, 2016, 10:51:32 AM

Previous topic - Next topic

Hervé

Dear Phil,

As you know, I'm developing a plugin that allows to import and export models to a database.

I would like to use the ArchiveMgr class to access model images. This class has got public methods to load and save from files but I would prefer not creating temporary files.

I would like to add two public methods :

  • public byte[] getEntry(String path) { return BYTE_ARRAY_STORAGE.getEntry(path); }
  • public void addByteContentEntry(String path, byte[] bytes) { BYTE_ARRAY_STORAGE.addByteContentEntry(path, bytes); }

How do you wish to proceed ?

Thanks in advance
Best regards
Hervé

Phil Beauvoir

Hi Hervé,

Ideally access to BYTE_ARRAY_STORAGE stays hidden from the public API, as it's part of the "plumbing".

If you can find another way to do it, that would be good. If you can't then I can consider adding the methods as API.

But I need to think about the dangers, if any.

getEntry(String path)is not so bad, but exposing addByteContentEntry(path, bytes) then the user needs to think about the entry name. Take a look at how addByteContentEntry(path, bytes) is used in the code and see if there are any dangers.

Regards,

Phil
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Hervé

Hi Phil,

Thanks for your quick answer. I do not see other way (but if someone does, I'm interested  ;D).

The BYTE_ARRAY_STORAGE content is already exposed through public methods :

  • createImage (which is public) returns an Image from the BYTE_ARRAY_STORAGE. I just need the byte[] to avoid converting back the Image to a byte[].
  • addImagesFromFile (which is also public) calls BYTE_ARRAY_STORAGE.addByteContentEntry with a byte[] read from a file. I just would like to directly provide the byte[] to avoid to create a temporary file.

To my opinion, these two methods do not add any danger.

Best regards
Hervé

Phil Beauvoir

Look what's going on here:


        // Is this already in the cache?
        String entryName = BYTE_ARRAY_STORAGE.getKey(bytes);

        // No, so create a new one
        if(entryName == null) {
            // Is this actually a valid Image file? Test it...
            testImageBytesValid(bytes);

            // OK, add the bytes
            entryName = createArchiveImagePathname(file);
            BYTE_ARRAY_STORAGE.addByteContentEntry(entryName, bytes);
        }


Add bytes to BYTE_ARRAY_STORAGE consists of (1) Checking if they are already in the cache, (2) Testing bytes are actually image data.
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Hervé

Hi Phil,

My point is that the export records the entryName and the byte[] that is stored in BYTE_ARRAY_STORAGE (using the getEntry method).

I was expecting the import method to put back exactly the same information (therefore I configured both parameters).

... Like what is done in the loadImagesFromModelFile where you do not check if the data read from the file is an image as you trust the *.archimate file. The same way, I trust my database.

But I don't really mind. If you feel safer, the code might be :

public byte[] getEntry(String path) {
        return BYTE_ARRAY_STORAGE.getEntry(path);
}

public String addByteContentEntry(String path, byte[] bytes) throws IOException {
        // Is this already in the cache?
        String entryName = BYTE_ARRAY_STORAGE.getKey(bytes);

        // No, so create a new one
        if(entryName == null) {
            // Is this actually a valid Image file? Test it...
            testImageBytesValid(bytes);

            // OK, add the bytes
            entryName = path;
            BYTE_ARRAY_STORAGE.addByteContentEntry(entryName, bytes);
        }

        return entryName;
}


I already calculate a md5 on the byte[] in order to store only once the images that are the same across the models. I will just manage the case when the entryName returned by the addByteContentEntry method is not the same as the one stored in the database. It should not happen but just in case ...

Thanks
Best regards
Hervé

Phil Beauvoir

That's pretty much what I came up with.

Committed to master in GitHub.

Can you check I didn't break anything?

Phil
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Hervé

Sure.

Thanks
Best regards
Hervé

Hervé

Hi Phil,

It works perfectly well  ;D.

I would suggest to add the following lines to the IArchiveManager class as well :

    /**
     * Get image bytes given its entry name
     * @param entryName The entry name (its path)
     * @return Return The image bytes
     */
    public byte[] getBytesFromEntry(String entryName);
   
    /**
     * Records an image from a byte array
     * @param pathThe image path
     * @param bytes The image
     * @return Returns the image path. If the image was already existing in the cache, the path returned may be distinct from the one given in parameter.
     */
    public String addByteContentEntry(String path, byte[] bytes) throws IOException;


When do you plan to release a 3.3.3 version that includes this update that I can release my plugin ?

Thanks
Best regards
Hervé

Hervé

I shouted victory too soon ...

You locked your application a bit too much for me mate.

It effectively works very well when ran from inside Eclipse in debug mode but then, I compiled Archi to an exe file and it didn't go well ...

When I run my plugin inside the exe I compiled myself, I've got the following runtime exception :
Quotejava.lang.NoClassDefFoundError: com/archimatetool/editor/model/impl/ArchiveManager

Any idea

thanks and regards
Hervé

Phil Beauvoir

Depends how you are using it. It should be through the API interface:

IArchiveManager archiveManager = IArchiveManager.createArchiveManager(model);

And the plug-in should declare a dependency on com.archimatetool.editor
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

Hervé

Hi Phil,

I had too much the head in the grindstone ... I went to bed early yesterday without thinking about Archi and today the solution came to me ...

I had forgotten to copy over the com.archimatetool.editor.jar file before testing.

Anyway, it works fine now. Thank you very much for your help on this subject  ;D

Best regards
Hervé