Exclude filter not working for filevault-package-maven-plugin - adobe

I have a content package with nodes I would like to exclude when this package is installed on AEM 6.5. The exclude configuration is defined in filter.xml (META-INF/vault/filter.xml).
Below is a representation of my filter.xml
<?xml version="1.0" encoding="UTF-8"?>
<workspaceFilter version="1.0">
<filter root="/apps/amzn-biz">
<exclude pattern="/apps/amzn-biz/i18n(.*)"/>
</filter>
<filter root="/apps/sling"/>
</workspaceFilter>
My pom.xml has below configuration
<!-- ====================================================================== -->
<!-- V A U L T P A C K A G E P L U G I N S -->
<!-- ====================================================================== -->
<plugin>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>filevault-package-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<group>amzn-biz</group>
<acHandling>merge_preserve</acHandling>
<packageType>content</packageType>
<embeddeds>
<embedded>
<groupId>com.amazon.business</groupId>
<artifactId>amzn-biz-foundation.core</artifactId>
<target>/apps/amzn-biz/install</target>
</embedded>
</embeddeds>
<subPackages>
<subPackage>
<groupId>com.adobe.cq</groupId>
<artifactId>core.wcm.components.all</artifactId>
<filter>true</filter>
</subPackage>
<subPackage>
<groupId>com.adobe.cq</groupId>
<artifactId>core.wcm.components.examples</artifactId>
<filter>true</filter>
</subPackage>
</subPackages>
</configuration>
</plugin>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>content-package-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<verbose>true</verbose>
<failOnError>true</failOnError>
</configuration>
</plugin>
I have tried multiple things by changing my exclude patterns to ./i18n. but it has not worked for me.
I have also tried adding filterSource to filevault-package-maven-plugin configuration but then i get the error Project contains filter.xml in META-INF/vault but also specifies a filter source.

You have to remove the nodes from the content package. You should not have any content in your content package, that is not explicitly covered by a filter-rule.
Your problem is weird backward-compatibility. At least in CQ5 were no filter-modes (mode="replace|merge|update") yet. In those days the rule was, that all content covered by a filter-rule is replaced. All other content is merged. When the filter-modes were introduced, they became non-intuitive but backward-compatible. In your case the i18n folder is merged.
Rule of thumb: A content package that is imported and exported again should be identical. (this would not be the case for you)
For more details see the table at https://jackrabbit.apache.org/filevault/filter.html#Usage_for_Import.2FInstallation for more information. For your i18n folder it says:
nodes which are ancestors of covered rules: deserialized from content package (for backwards compatibility reasons), nodes which are
not ancestors of covered rules: not touched. One should not rely on
this behaviour, i.e. all items in the content package should always be
covered by some filter rule to make the behaviour more explicit.

The issue may be relating to <packageType>content</packageType> instead of filter.xml. This type cannot have sub-packages nor embedded bundles. If <embeddeds> and <subPackages> are needed for the project, use <packageType>mixed</packageType> will reduce chance of unexpected build and installation behaviors.
The list of package types and behaviors are as following:
application: Package consists pure application content (aka. /apps/*). Does not contain any subpackages nor OSGi configuration or bundles.
content: Package consists only of content and user defined configuration. Does not contain any subpackages nor OSGi configuration or bundles.
container: Package only contains sub packages and OSGi configuration and bundles.
mixed: Catch all type for a combination of the above.
More details can be found at http://jackrabbit.apache.org/filevault-package-maven-plugin/generate-metadata-mojo.html#packageType

Related

How to import a type incuding its package name

I'm using last version of openapi-generator-maven-plugin (6.0.1)
In order to handle some binary data properly I need to use typeMappings configuration as described here : https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-maven-plugin/README.md
So I configure my pom as following :
<configuration>
<typeMappings>
<typeMapping>string+binary=org.springframework.core.io.Resource</typeMapping>
</typeMappings>
</configuration>
But the code-generator understand it as a OrgSpringframeworkCoreIoResource class. How can I tell it not to camel case my parameter?
I finally undertand the problem : it's a 2 step configuration.
<!-- First we map the OpenAPI type to a keyword -->
<typeMappings>
<typeMapping>string+binary=Resource</typeMapping>
</typeMappings>
<!-- Then we attach the keyword to an existing type -->
<importMappings>Resource=org.springframework.core.io.Resource</importMappings>
That's way it works!

For a xamarin.iOS app, how to identify assembly that a symbol comes from

When I build an archive for my Xamarin Forms iOS app, the linker is eliminating some required symbols for Firebase. A build work fine. I know that is can use --linkskip to keep an assembly but how do you identify which assembly needs to be specified to preserve the symbol.
This is helpful if using [Preserve] on some assemblies is impossible (e.g. 3rd party code) or as a temporary workaround for a bug.
You can have a look at Skipping Assemblies , when which assembly is not used or occurs a bug with which assembly , you can identify it .
I found the Object Browser extremely helpful for that purpose. If you set the browse scope to "My Solution" it'll show you all classes that are defined in and referenced from your current solution. From thereon you can search for the classes that are missing during runtime (searching may take some seconds, depending on your solutions size). Select the respective class and delete the search text. The selected class remains selected and you can see the container (i.e. assembly) the class is defined in and add it to linkskip.
On a side note: When your project grows there may be many exceptions for the linker to add. While it may be possible to add all of these with linkskip, a linker XML definition may be more feasible. To use this, add an XML file with the build target LinkDescription. Within that file add the assemblies and types to preserve
<linker>
<assembly fullname="Firebase.XXX">
<type fullname="*" /> <-- Preserve everything from that assembly -->
</assembly>
</linker>

Remove browser layer on Plone 5

In previous versions of Plone, QuickInstaller took care of automagically removing some stuff on uninstall time; that was the case of browser layers and resource registry resources. Now in Plone 5 is a best practice to include a GenericSetup profile to explicitly uninstall those thins.
I folowed up Keul's blog post on uninstalls and added a browserlayer.xml file to my package uninstall profile as follows:
<?xml version="1.0"?>
<layers>
<layer name="collective.fingerpointing" remove="true" />
</layers>
but my package is not removing it.
any hints?
code is in: https://github.com/collective/collective.fingerpointing/pull/6
test results are in: https://travis-ci.org/collective/collective.fingerpointing/jobs/110195902
I'm just one test away of accomplish compatibility of my add-on!
For unregistering browser layers, the interface is ignored. Only the browser layer name is important. That has to match the name, under which the browser layer was registered before.
The problem was in the test: I was testing against the name of the interface and another package (in my case, plone.app.event) had a browser layer with the same name (IBrowserLayer):
(Pdb) registered_layers()[4]
<InterfaceClass plone.app.event.interfaces.IBrowserLayer>
I was using this:
def test_addon_layer_removed(self):
from plone.browserlayer.utils import registered_layers
layers = [l.getName() for l in registered_layers()]
self.assertNotIn('IBrowserLayer', layers)
I change it to the following:
def test_addon_layer_removed(self):
from collective.fingerpointing.interfaces import IBrowserLayer
from plone.browserlayer.utils import registered_layers
self.assertNotIn(IBrowserLayer, registered_layers())
That's why is important to have the right tests in place.

Add computed metadata to catalog for dexterity object (plone 4)

I want to create a catalog metadata with a computed string. So following Aspeli's book and the developer manual I proceeded to create an indexer:
# indexer.py
#grok.adapter(Entry, name='bind_representation')
#indexer(Entry)
def bindIndexer(context):
print str(IBindRepresentable(context))
return str(IBindRepresentable(context))
and register the index with genericSetup:
<!-- profiles/default/catalog.xml -->
<?xml version="1.0"?>
<object name="portal_catalog" meta_type="Plone Catalog Tool">
<index name="bind_representation" meta_type="ZCTextIndex">
<!-- I tried with meta_type="FieldIndex" too -->
<indexed_attr value="bind_representation"/>
<!-- copied from other text metadata -->
<extra name="index_type" value="Okapi BM25 Rank"/>
<extra name="lexicon_id" value="plaintext_lexicon"/>
</index>
</object>
The problems are: (1) only the index is registered, not the metadata, and (2) After reindex all the zodb, bind_representation still doesn't find any entry to index, even when they are.
The examples cited only deal with pre-existent indexes, so I'm not sure about the content of catalog.xml. bindIndexer seems not to be called at all, since its print statement is never executed. I copied bindIndexer to entry.py too, to get sure it wasn't being ignored, but still nothing.
What am I missing?
Thanks.
1- In order to add a new metadata, you have to use this syntax:
<?xml version="1.0"?>
<object name="portal_catalog" meta_type="Plone Catalog Tool">
...
<column value="bind_representation"/>
</object>
2a- you are adapting your content class, you should adapt your content interface (IEntry most likely).
2b- you are using a ZCTextIndex: that index won't show you all entries anyway (even following the previous point) because it's based on a lexicon. You should probably use this instead (unless you have specific bounds):
<index name="bind_representation" meta_type="FieldIndex">
<indexed_attr value="bind_representation"/>
</index>
More info:
http://bluebream.zope.org/doc/1.0/manual/componentarchitecture.html#adapters
http://maurits.vanrees.org/weblog/archive/2009/12/catalog

quickinstaller.installProduct 'installs' stuff that doesn't even exist. How do I raise an exception?

I have a config.py in my product, having:
DEPENDENCIES = ['bbbbbbbbbbbb'] #This doesn't exist
And in my setuphandlers.py:
for dependency in DEPENDENCIES:
if not quickinstaller.isProductInstalled(dependency):
quickinstaller.installProduct(dependency)
And now I have a bbbbbbbbbbbb entry in my portal_quickinstaller's Contents tab. (http://localhost:8080/Plone/portal_quickinstaller/manage_main).
What should I do to make the dependencies section 'complain' (raise an exception, whatever) if the dependency doesn't exist? Thanks!
EDIT: I've found a hack using quickinstaller.getProductVersion: if nothing comes, it doesn't exist. Is there another way?
You can use something like this:
def install_dependencies(site):
"""Install required products"""
qi = getToolByName(site, 'portal_quickinstaller')
for product in DEPENDENCIES:
if not qi.isProductInstalled(product):
if qi.isProductInstallable(product):
qi.installProduct(product)
else:
raise "Product %s not installable" % product
The normal way of declaring deps is to use metadata.xml:
<metadata>
<dependencies>
<dependency>profile-plone.app.iterate:plone.app.iterate</dependency>
</dependencies>
</metadata>
This will add the plone.app.iterate package, as its install profile name is plone.app.iterate. The vast majority of these are called default, e.g.:
<metadata>
<dependencies>
<dependency>profile-plone.app.jquerytools:default</dependency>
<dependency>profile-archetypes.referencebrowserwidget:default</dependency>
<dependency>profile-plone.app.imaging:default</dependency>
<dependency>profile-plone.app.registry:default</dependency>
<dependency>profile-plone.portlet.collection:default</dependency>
</dependencies>
</metadata>
Of course, this only works if the product you're trying to install has a Generic Setup profile, but all but the very oldest do.
I guess it depends why you might have a product that doesn't exist.
Normally, you wouldn't be testing this here - you'd put your dependency in setup.py, and then your buildout fails if the product doesn't exist.
If, though, you have a product that may use a second product if it exists (for instance, SQLAlchemy needs one or more python DBAPI eggs, but no specific one), then I would think you need to do the usual: which is to wrap an import of some module in the product with a try/except and not do the install if the import fails.

Resources