Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
appinventor-sources
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
appinventor-sources
Commits
9db6dc29
Commit
9db6dc29
authored
May 08, 2020
by
Bart Mathijssen
Committed by
Jeffrey Schiller
Jun 12, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement metadata annotations for extensions
parent
03a021a5
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
189 additions
and
0 deletions
+189
-0
appinventor/buildserver/src/com/google/appinventor/buildserver/Compiler.java
...rver/src/com/google/appinventor/buildserver/Compiler.java
+71
-0
appinventor/components/src/com/google/appinventor/components/annotations/UsesActivityMetadata.java
...inventor/components/annotations/UsesActivityMetadata.java
+31
-0
appinventor/components/src/com/google/appinventor/components/annotations/UsesApplicationMetadata.java
...entor/components/annotations/UsesApplicationMetadata.java
+31
-0
appinventor/components/src/com/google/appinventor/components/common/ComponentDescriptorConstants.java
...entor/components/common/ComponentDescriptorConstants.java
+2
-0
appinventor/components/src/com/google/appinventor/components/scripts/ComponentListGenerator.java
...ppinventor/components/scripts/ComponentListGenerator.java
+2
-0
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
...le/appinventor/components/scripts/ComponentProcessor.java
+52
-0
No files found.
appinventor/buildserver/src/com/google/appinventor/buildserver/Compiler.java
View file @
9db6dc29
...
@@ -154,6 +154,10 @@ public final class Compiler {
...
@@ -154,6 +154,10 @@ public final class Compiler {
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
activitiesNeeded
=
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
activitiesNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
metadataNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
activityMetadataNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
broadcastReceiversNeeded
=
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
broadcastReceiversNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
libsNeeded
=
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
libsNeeded
=
...
@@ -511,6 +515,56 @@ public final class Compiler {
...
@@ -511,6 +515,56 @@ public final class Compiler {
System
.
out
.
println
(
"Component activities needed, n = "
+
n
);
System
.
out
.
println
(
"Component activities needed, n = "
+
n
);
}
}
/**
* Generate a set of conditionally included metadata needed by this project.
*/
@VisibleForTesting
void
generateMetadata
()
{
try
{
loadJsonInfo
(
metadataNeeded
,
ComponentDescriptorConstants
.
METADATA_TARGET
);
}
catch
(
IOException
e
)
{
// This is fatal.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Metadata"
));
}
catch
(
JSONException
e
)
{
// This is fatal, but shouldn't actually ever happen.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Metadata"
));
}
int
n
=
0
;
for
(
String
type
:
metadataNeeded
.
keySet
())
{
n
+=
metadataNeeded
.
get
(
type
).
size
();
}
System
.
out
.
println
(
"Component metadata needed, n = "
+
n
);
}
/**
* Generate a set of conditionally included activity metadata needed by this project.
*/
@VisibleForTesting
void
generateActivityMetadata
()
{
try
{
loadJsonInfo
(
activityMetadataNeeded
,
ComponentDescriptorConstants
.
ACTIVITY_METADATA_TARGET
);
}
catch
(
IOException
e
)
{
// This is fatal.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Activity Metadata"
));
}
catch
(
JSONException
e
)
{
// This is fatal, but shouldn't actually ever happen.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Activity Metadata"
));
}
int
n
=
0
;
for
(
String
type
:
activityMetadataNeeded
.
keySet
())
{
n
+=
activityMetadataNeeded
.
get
(
type
).
size
();
}
System
.
out
.
println
(
"Component metadata needed, n = "
+
n
);
}
/*
/*
* Generate a set of conditionally included broadcast receivers needed by this project.
* Generate a set of conditionally included broadcast receivers needed by this project.
*/
*/
...
@@ -1012,6 +1066,20 @@ public final class Compiler {
...
@@ -1012,6 +1066,20 @@ public final class Compiler {
out
.
write
(
" <data android:mimeType=\"text/plain\" />\n"
);
out
.
write
(
" <data android:mimeType=\"text/plain\" />\n"
);
out
.
write
(
" </intent-filter>\n"
);
out
.
write
(
" </intent-filter>\n"
);
}
}
Set
<
Map
.
Entry
<
String
,
Set
<
String
>>>
metadataElements
=
activityMetadataNeeded
.
entrySet
();
// If any component needs to register additional activity metadata,
// insert them into the manifest here.
if
(!
metadataElements
.
isEmpty
())
{
for
(
Map
.
Entry
<
String
,
Set
<
String
>>
metadataElementSetPair
:
metadataElements
)
{
Set
<
String
>
metadataElementSet
=
metadataElementSetPair
.
getValue
();
for
(
String
metadataElement
:
metadataElementSet
)
{
out
.
write
(
metadataElement
);
}
}
}
out
.
write
(
" </activity>\n"
);
out
.
write
(
" </activity>\n"
);
// Companion display a splash screen... define it's activity here
// Companion display a splash screen... define it's activity here
...
@@ -1027,6 +1095,7 @@ public final class Compiler {
...
@@ -1027,6 +1095,7 @@ public final class Compiler {
// Collect any additional <application> subelements into a single set.
// Collect any additional <application> subelements into a single set.
Set
<
Map
.
Entry
<
String
,
Set
<
String
>>>
subelements
=
Sets
.
newHashSet
();
Set
<
Map
.
Entry
<
String
,
Set
<
String
>>>
subelements
=
Sets
.
newHashSet
();
subelements
.
addAll
(
activitiesNeeded
.
entrySet
());
subelements
.
addAll
(
activitiesNeeded
.
entrySet
());
subelements
.
addAll
(
metadataNeeded
.
entrySet
());
subelements
.
addAll
(
broadcastReceiversNeeded
.
entrySet
());
subelements
.
addAll
(
broadcastReceiversNeeded
.
entrySet
());
...
@@ -1140,6 +1209,8 @@ public final class Compiler {
...
@@ -1140,6 +1209,8 @@ public final class Compiler {
compiler
.
generateAssets
();
compiler
.
generateAssets
();
compiler
.
generateActivities
();
compiler
.
generateActivities
();
compiler
.
generateMetadata
();
compiler
.
generateActivityMetadata
();
compiler
.
generateBroadcastReceivers
();
compiler
.
generateBroadcastReceivers
();
compiler
.
generateLibNames
();
compiler
.
generateLibNames
();
compiler
.
generateNativeLibNames
();
compiler
.
generateNativeLibNames
();
...
...
appinventor/components/src/com/google/appinventor/components/annotations/UsesActivityMetadata.java
0 → 100644
View file @
9db6dc29
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations
;
import
com.google.appinventor.components.annotations.androidmanifest.MetaDataElement
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Annotation to indicate any additional metadata required by
* a component so that corresponding <meta-data> elements can be added
* to AndroidManifest.xml.
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
UsesActivityMetadata
{
/**
* An array containing each {@link MetaDataElement}
* that is required by the component.
*
* @return the array containing the relevant metadata
*/
MetaDataElement
[]
metaDataElements
();
}
appinventor/components/src/com/google/appinventor/components/annotations/UsesApplicationMetadata.java
0 → 100644
View file @
9db6dc29
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations
;
import
com.google.appinventor.components.annotations.androidmanifest.MetaDataElement
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Annotation to indicate any additional metadata required by
* a component so that corresponding <meta-data> elements can be added
* to AndroidManifest.xml.
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
UsesApplicationMetadata
{
/**
* An array containing each {@link MetaDataElement}
* that is required by the component.
*
* @return the array containing the relevant metadata
*/
MetaDataElement
[]
metaDataElements
();
}
appinventor/components/src/com/google/appinventor/components/common/ComponentDescriptorConstants.java
View file @
9db6dc29
...
@@ -20,6 +20,8 @@ public final class ComponentDescriptorConstants {
...
@@ -20,6 +20,8 @@ public final class ComponentDescriptorConstants {
public
static
final
String
ASSET_DIRECTORY
=
"component"
;
public
static
final
String
ASSET_DIRECTORY
=
"component"
;
public
static
final
String
ASSETS_TARGET
=
"assets"
;
public
static
final
String
ASSETS_TARGET
=
"assets"
;
public
static
final
String
ACTIVITIES_TARGET
=
"activities"
;
public
static
final
String
ACTIVITIES_TARGET
=
"activities"
;
public
static
final
String
METADATA_TARGET
=
"metadata"
;
public
static
final
String
ACTIVITY_METADATA_TARGET
=
"activityMetadata"
;
public
static
final
String
LIBRARIES_TARGET
=
"libraries"
;
public
static
final
String
LIBRARIES_TARGET
=
"libraries"
;
public
static
final
String
NATIVE_TARGET
=
"native"
;
public
static
final
String
NATIVE_TARGET
=
"native"
;
public
static
final
String
PERMISSIONS_TARGET
=
"permissions"
;
public
static
final
String
PERMISSIONS_TARGET
=
"permissions"
;
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentListGenerator.java
View file @
9db6dc29
...
@@ -81,6 +81,8 @@ public final class ComponentListGenerator extends ComponentProcessor {
...
@@ -81,6 +81,8 @@ public final class ComponentListGenerator extends ComponentProcessor {
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
NATIVE_TARGET
,
component
.
nativeLibraries
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
NATIVE_TARGET
,
component
.
nativeLibraries
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ASSETS_TARGET
,
component
.
assets
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ASSETS_TARGET
,
component
.
assets
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ACTIVITIES_TARGET
,
component
.
activities
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ACTIVITIES_TARGET
,
component
.
activities
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
METADATA_TARGET
,
component
.
metadata
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ACTIVITY_METADATA_TARGET
,
component
.
activityMetadata
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ANDROIDMINSDK_TARGET
,
Collections
.
singleton
(
Integer
.
toString
(
component
.
getAndroidMinSdk
())));
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ANDROIDMINSDK_TARGET
,
Collections
.
singleton
(
Integer
.
toString
(
component
.
getAndroidMinSdk
())));
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
BROADCAST_RECEIVERS_TARGET
,
component
.
broadcastReceivers
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
BROADCAST_RECEIVERS_TARGET
,
component
.
broadcastReceivers
);
appendConditionalComponentInfo
(
component
,
sb
);
appendConditionalComponentInfo
(
component
,
sb
);
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
View file @
9db6dc29
...
@@ -15,6 +15,8 @@ import com.google.appinventor.components.annotations.SimpleFunction;
...
@@ -15,6 +15,8 @@ import com.google.appinventor.components.annotations.SimpleFunction;
import
com.google.appinventor.components.annotations.SimpleObject
;
import
com.google.appinventor.components.annotations.SimpleObject
;
import
com.google.appinventor.components.annotations.SimpleProperty
;
import
com.google.appinventor.components.annotations.SimpleProperty
;
import
com.google.appinventor.components.annotations.SimpleBroadcastReceiver
;
import
com.google.appinventor.components.annotations.SimpleBroadcastReceiver
;
import
com.google.appinventor.components.annotations.UsesActivityMetadata
;
import
com.google.appinventor.components.annotations.UsesApplicationMetadata
;
import
com.google.appinventor.components.annotations.UsesAssets
;
import
com.google.appinventor.components.annotations.UsesAssets
;
import
com.google.appinventor.components.annotations.UsesLibraries
;
import
com.google.appinventor.components.annotations.UsesLibraries
;
import
com.google.appinventor.components.annotations.UsesNativeLibraries
;
import
com.google.appinventor.components.annotations.UsesNativeLibraries
;
...
@@ -671,6 +673,16 @@ public abstract class ComponentProcessor extends AbstractProcessor {
...
@@ -671,6 +673,16 @@ public abstract class ComponentProcessor extends AbstractProcessor {
*/
*/
protected
final
Set
<
String
>
activities
;
protected
final
Set
<
String
>
activities
;
/**
* Metadata required by this component.
*/
protected
final
Set
<
String
>
metadata
;
/**
* Activity metadata required by this component.
*/
protected
final
Set
<
String
>
activityMetadata
;
/**
/**
* Broadcast receivers required by this component.
* Broadcast receivers required by this component.
*/
*/
...
@@ -753,6 +765,8 @@ public abstract class ComponentProcessor extends AbstractProcessor {
...
@@ -753,6 +765,8 @@ public abstract class ComponentProcessor extends AbstractProcessor {
nativeLibraries
=
Sets
.
newHashSet
();
nativeLibraries
=
Sets
.
newHashSet
();
assets
=
Sets
.
newHashSet
();
assets
=
Sets
.
newHashSet
();
activities
=
Sets
.
newHashSet
();
activities
=
Sets
.
newHashSet
();
metadata
=
Sets
.
newHashSet
();
activityMetadata
=
Sets
.
newHashSet
();
broadcastReceivers
=
Sets
.
newHashSet
();
broadcastReceivers
=
Sets
.
newHashSet
();
classNameAndActionsBR
=
Sets
.
newHashSet
();
classNameAndActionsBR
=
Sets
.
newHashSet
();
designerProperties
=
Maps
.
newTreeMap
();
designerProperties
=
Maps
.
newTreeMap
();
...
@@ -1099,6 +1113,8 @@ public abstract class ComponentProcessor extends AbstractProcessor {
...
@@ -1099,6 +1113,8 @@ public abstract class ComponentProcessor extends AbstractProcessor {
componentInfo
.
nativeLibraries
.
addAll
(
parentComponent
.
nativeLibraries
);
componentInfo
.
nativeLibraries
.
addAll
(
parentComponent
.
nativeLibraries
);
componentInfo
.
assets
.
addAll
(
parentComponent
.
assets
);
componentInfo
.
assets
.
addAll
(
parentComponent
.
assets
);
componentInfo
.
activities
.
addAll
(
parentComponent
.
activities
);
componentInfo
.
activities
.
addAll
(
parentComponent
.
activities
);
componentInfo
.
metadata
.
addAll
(
parentComponent
.
metadata
);
componentInfo
.
activityMetadata
.
addAll
(
parentComponent
.
activityMetadata
);
componentInfo
.
broadcastReceivers
.
addAll
(
parentComponent
.
broadcastReceivers
);
componentInfo
.
broadcastReceivers
.
addAll
(
parentComponent
.
broadcastReceivers
);
// TODO(Will): Remove the following call once the deprecated
// TODO(Will): Remove the following call once the deprecated
// @SimpleBroadcastReceiver annotation is removed. It should
// @SimpleBroadcastReceiver annotation is removed. It should
...
@@ -1187,6 +1203,42 @@ public abstract class ComponentProcessor extends AbstractProcessor {
...
@@ -1187,6 +1203,42 @@ public abstract class ComponentProcessor extends AbstractProcessor {
}
}
}
}
// Gather the required metadata and build their element strings.
UsesApplicationMetadata
usesApplicationMetadata
=
element
.
getAnnotation
(
UsesApplicationMetadata
.
class
);
if
(
usesApplicationMetadata
!=
null
)
{
try
{
for
(
MetaDataElement
me
:
usesApplicationMetadata
.
metaDataElements
())
{
updateWithNonEmptyValue
(
componentInfo
.
metadata
,
metaDataElementToString
(
me
));
}
}
catch
(
IllegalAccessException
e
)
{
messager
.
printMessage
(
Diagnostic
.
Kind
.
ERROR
,
"IllegalAccessException when gathering "
+
"application metadata and subelements for component "
+
componentInfo
.
name
);
throw
new
RuntimeException
(
e
);
}
catch
(
InvocationTargetException
e
)
{
messager
.
printMessage
(
Diagnostic
.
Kind
.
ERROR
,
"InvocationTargetException when gathering "
+
"application metadata and subelements for component "
+
componentInfo
.
name
);
throw
new
RuntimeException
(
e
);
}
}
// Gather the required activity metadata and build their element strings.
UsesActivityMetadata
usesActivityMetadata
=
element
.
getAnnotation
(
UsesActivityMetadata
.
class
);
if
(
usesActivityMetadata
!=
null
)
{
try
{
for
(
MetaDataElement
me
:
usesActivityMetadata
.
metaDataElements
())
{
updateWithNonEmptyValue
(
componentInfo
.
activityMetadata
,
metaDataElementToString
(
me
));
}
}
catch
(
IllegalAccessException
e
)
{
messager
.
printMessage
(
Diagnostic
.
Kind
.
ERROR
,
"IllegalAccessException when gathering "
+
"application metadata and subelements for component "
+
componentInfo
.
name
);
throw
new
RuntimeException
(
e
);
}
catch
(
InvocationTargetException
e
)
{
messager
.
printMessage
(
Diagnostic
.
Kind
.
ERROR
,
"InvocationTargetException when gathering "
+
"application metadata and subelements for component "
+
componentInfo
.
name
);
throw
new
RuntimeException
(
e
);
}
}
// Gather the required broadcast receivers and build their element strings.
// Gather the required broadcast receivers and build their element strings.
UsesBroadcastReceivers
usesBroadcastReceivers
=
element
.
getAnnotation
(
UsesBroadcastReceivers
.
class
);
UsesBroadcastReceivers
usesBroadcastReceivers
=
element
.
getAnnotation
(
UsesBroadcastReceivers
.
class
);
if
(
usesBroadcastReceivers
!=
null
)
{
if
(
usesBroadcastReceivers
!=
null
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment