Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ public final class ApplicationDescriptor

private final String url;

private final ApplicationType type;

private ApplicationDescriptor( final Builder builder )
{
this.key = requireNonNull( builder.key, "key cannot be null" );
this.type = builder.type != null ? builder.type : ApplicationType.BUNDLE;
this.description = builder.description != null ? builder.description : "";
this.descriptionI18nKey = builder.descriptionI18nKey;
this.icon = builder.icon;
Expand All @@ -50,6 +53,11 @@ public ApplicationKey getKey()
return key;
}

public ApplicationType getType()
{
return type;
}

public String getDescription()
{
return description;
Expand Down Expand Up @@ -109,16 +117,17 @@ public boolean equals( final Object o )

final ApplicationDescriptor that = (ApplicationDescriptor) o;

return key.equals( that.key ) && Objects.equals( description, that.description ) && Objects.equals( icon, that.icon ) &&
Objects.equals( descriptionI18nKey, that.descriptionI18nKey ) && Objects.equals( title, that.title ) &&
Objects.equals( titleI18nKey, that.titleI18nKey ) && Objects.equals( vendorName, that.vendorName ) &&
Objects.equals( vendorUrl, that.vendorUrl ) && Objects.equals( url, that.url ) && schemaConfig.equals( that.schemaConfig );
return key.equals( that.key ) && type == that.type && Objects.equals( description, that.description ) &&
Objects.equals( icon, that.icon ) && Objects.equals( descriptionI18nKey, that.descriptionI18nKey ) &&
Objects.equals( title, that.title ) && Objects.equals( titleI18nKey, that.titleI18nKey ) &&
Objects.equals( vendorName, that.vendorName ) && Objects.equals( vendorUrl, that.vendorUrl ) &&
Objects.equals( url, that.url ) && schemaConfig.equals( that.schemaConfig );
}

@Override
public int hashCode()
{
return Objects.hash( key, description, icon, title, titleI18nKey, vendorName, vendorUrl, url, schemaConfig );
return Objects.hash( key, type, description, icon, title, titleI18nKey, vendorName, vendorUrl, url, schemaConfig );
}

public static Builder create()
Expand Down Expand Up @@ -146,6 +155,8 @@ public static final class Builder

private String url;

private ApplicationType type;

private final GenericValue.ObjectBuilder schemaConfig = GenericValue.newObject();

private Builder()
Expand All @@ -158,6 +169,12 @@ public Builder key( final ApplicationKey key )
return this;
}

public Builder type( final ApplicationType type )
{
this.type = type;
return this;
}

public Builder description( final String description )
{
this.description = description;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.enonic.xp.app;

public enum ApplicationType
{
STATIC, BUNDLE
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ public final class SchemaNodePropertyNames
{
public static final String RESOURCE = "resource";

public static final String MIME_TYPE = "mimeType";

public static final String ICON = "icon";

private SchemaNodePropertyNames()
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@ void getters()
assertSame( icon, desc.getIcon() );
}

@Test
void default_type_is_bundle()
{
final ApplicationDescriptor desc = ApplicationDescriptor.create().key( ApplicationKey.from( "app" ) ).build();

assertEquals( ApplicationType.BUNDLE, desc.getType() );
}

@Test
void type()
{
final ApplicationKey key = ApplicationKey.from( "app" );

final ApplicationDescriptor staticDesc = ApplicationDescriptor.create().key( key ).type( ApplicationType.STATIC ).build();
final ApplicationDescriptor bundleDesc = ApplicationDescriptor.create().key( key ).type( ApplicationType.BUNDLE ).build();
final ApplicationDescriptor defaultDesc = ApplicationDescriptor.create().key( key ).build();

assertEquals( ApplicationType.STATIC, staticDesc.getType() );
assertEquals( ApplicationType.BUNDLE, bundleDesc.getType() );
assertEquals( bundleDesc, defaultDesc );
assertNotEquals( staticDesc, bundleDesc );
assertNotEquals( staticDesc.hashCode(), bundleDesc.hashCode() );
}

@Test
void null_description()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.enonic.xp.core.impl.app;

import com.enonic.xp.app.ApplicationType;

public class AppInfo
{
public String name;

public ApplicationType type = ApplicationType.BUNDLE;

public boolean hasCmsDescriptor;

public String title;

public String vendorName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ private static AppInfo findAppInfo( final Path file )
{
final Manifest man;
final String descriptorYaml;
final boolean hasCmsDescriptor;

try (JarFile jarFile = new JarFile( file.toFile() ))
{
Expand All @@ -60,8 +61,10 @@ private static AppInfo findAppInfo( final Path file )
throw new ApplicationInvalidException( "Not a valid application." );
}

hasCmsDescriptor = SchemaResourcePaths.CMS_DESCRIPTOR_PATHS.stream().anyMatch( path -> jarFile.getJarEntry( path ) != null );
}
final AppInfo appInfo = new AppInfo();
appInfo.hasCmsDescriptor = hasCmsDescriptor;
final Attributes attrs = man.getMainAttributes();
appInfo.name = attrs.getValue( Constants.BUNDLE_SYMBOLICNAME );
appInfo.version = Optional.ofNullable( attrs.getValue( Constants.BUNDLE_VERSION ) ).orElse( "0.0.0" );
Expand All @@ -83,6 +86,7 @@ private static AppInfo findAppInfo( final Path file )
YmlApplicationDescriptorParser.parse( descriptorYaml, ApplicationKey.from( appInfo.name ) ).build();
appInfo.title = descriptor.getTitle();
appInfo.vendorName = descriptor.getVendorName();
appInfo.type = descriptor.getType();
}
else
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.enonic.xp.core.impl.app;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import com.google.common.io.ByteSource;

/**
* Extracts schema resources (see {@link SchemaResourcePaths}) from an application jar.
* Keys of the returned map are paths relative to the {@code cms/} root, values are the resource contents.
*/
final class AppSchemaResolver
{
private AppSchemaResolver()
{
}

static Map<String, ByteSource> resolve( final ByteSource byteSource )
{
final Map<String, ByteSource> resources = new LinkedHashMap<>();
try (ZipInputStream zip = new ZipInputStream( byteSource.openBufferedStream() ))
{
ZipEntry entry;
while ( ( entry = zip.getNextEntry() ) != null )
{
if ( entry.isDirectory() )
{
continue;
}

final Matcher matcher = SchemaResourcePaths.SCHEMA_RESOURCE_PATTERN.matcher( entry.getName() );
if ( !matcher.matches() )
{
continue;
}

final ByteSource content = ByteSource.wrap( zip.readAllBytes() );

final String verbatimPath = firstNonNull( matcher.group( SchemaResourcePaths.PHRASES_PATH_GROUP ),
matcher.group( SchemaResourcePaths.ICON_PATH_GROUP ) );
if ( verbatimPath != null )
{
resources.put( verbatimPath, content );
}
else
{
// Both .yaml and .yml descriptors normalize to the same ".yaml" key.
// If a JAR contains both variants, .yaml wins regardless of zip entry order:
// put() lets .yaml overwrite, putIfAbsent() keeps .yml from replacing it.
final String path = matcher.group( SchemaResourcePaths.DESCRIPTOR_PATH_GROUP ) + ".yaml";

if ( "yaml".equals( matcher.group( SchemaResourcePaths.EXTENSION_GROUP ) ) )
{
resources.put( path, content );
}
else
{
resources.putIfAbsent( path, content );
}
}
}
}
catch ( IOException e )
{
throw new UncheckedIOException( e );
}
return resources;
}

private static String firstNonNull( final String first, final String second )
{
return first != null ? first : second;
}
}
Loading