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
713ff82b
Unverified
Commit
713ff82b
authored
Dec 02, 2020
by
Vishwas Adiga
Committed by
GitHub
Dec 01, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ability to include license files in extensions (#2326)
parent
33324c8a
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
119 additions
and
10 deletions
+119
-10
appinventor/appengine/src/com/google/appinventor/client/OdeMessages.java
...engine/src/com/google/appinventor/client/OdeMessages.java
+4
-0
appinventor/appengine/src/com/google/appinventor/client/editor/simple/ComponentDatabase.java
...e/appinventor/client/editor/simple/ComponentDatabase.java
+12
-1
appinventor/appengine/src/com/google/appinventor/client/editor/simple/palette/ComponentHelpWidget.java
...tor/client/editor/simple/palette/ComponentHelpWidget.java
+7
-0
appinventor/appengine/src/com/google/appinventor/client/editor/simple/palette/SimpleComponentDescriptor.java
...ient/editor/simple/palette/SimpleComponentDescriptor.java
+26
-0
appinventor/appengine/src/com/google/appinventor/server/DownloadServlet.java
...ne/src/com/google/appinventor/server/DownloadServlet.java
+3
-1
appinventor/appengine/src/com/google/appinventor/shared/simple/ComponentDatabaseInterface.java
...appinventor/shared/simple/ComponentDatabaseInterface.java
+14
-1
appinventor/components/src/com/google/appinventor/components/annotations/DesignerComponent.java
...appinventor/components/annotations/DesignerComponent.java
+10
-0
appinventor/components/src/com/google/appinventor/components/scripts/ComponentDescriptorGenerator.java
...ntor/components/scripts/ComponentDescriptorGenerator.java
+5
-2
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
...le/appinventor/components/scripts/ComponentProcessor.java
+17
-5
appinventor/components/src/com/google/appinventor/components/scripts/ExternalComponentGenerator.java
...ventor/components/scripts/ExternalComponentGenerator.java
+21
-0
No files found.
appinventor/appengine/src/com/google/appinventor/client/OdeMessages.java
View file @
713ff82b
...
...
@@ -1037,6 +1037,10 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
@Description
(
"Label of the link to a component's reference docs"
)
String
moreInformation
();
@DefaultMessage
(
"View license"
)
@Description
(
"Label of the link to a component's attribution license"
)
String
viewLicense
();
// Used in editor/youngandroid/YaFormEditor.java and YaBlocksEditor.java
@DefaultMessage
(
"Server error: could not load file. Please try again later!"
)
...
...
appinventor/appengine/src/com/google/appinventor/client/editor/simple/ComponentDatabase.java
View file @
713ff82b
...
...
@@ -255,6 +255,15 @@ class ComponentDatabase implements ComponentDatabaseInterface {
return
component
.
getIconName
();
}
@Override
public
String
getLicenseName
(
String
componentName
)
{
ComponentDefinition
component
=
components
.
get
(
componentName
);
if
(
component
==
null
)
{
throw
new
ComponentNotFoundException
(
componentName
);
}
return
component
.
getLicenseName
();
}
@Override
public
List
<
PropertyDefinition
>
getPropertyDefinitions
(
String
componentName
)
{
ComponentDefinition
component
=
components
.
get
(
componentName
);
...
...
@@ -341,7 +350,9 @@ class ComponentDatabase implements ComponentDatabaseInterface {
properties
.
containsKey
(
"helpUrl"
)
?
properties
.
get
(
"helpUrl"
).
asString
().
getString
()
:
""
,
Boolean
.
valueOf
(
properties
.
get
(
"showOnPalette"
).
asString
().
getString
()),
Boolean
.
valueOf
(
properties
.
get
(
"nonVisible"
).
asString
().
getString
()),
properties
.
get
(
"iconName"
).
asString
().
getString
(),
componentNode
.
toJson
());
properties
.
get
(
"iconName"
).
asString
().
getString
(),
properties
.
containsKey
(
"licenseName"
)
?
properties
.
get
(
"licenseName"
).
asString
().
getString
()
:
""
,
componentNode
.
toJson
());
findComponentProperties
(
component
,
properties
.
get
(
"properties"
).
asArray
());
findComponentBlockProperties
(
component
,
properties
.
get
(
"blockProperties"
).
asArray
());
findComponentEvents
(
component
,
properties
.
get
(
"events"
).
asArray
());
...
...
appinventor/appengine/src/com/google/appinventor/client/editor/simple/palette/ComponentHelpWidget.java
View file @
713ff82b
...
...
@@ -108,6 +108,13 @@ public final class ComponentHelpWidget extends AbstractPaletteItemWidget {
link
.
setStyleName
(
"ode-ComponentHelpPopup-Link"
);
inner
.
add
(
link
);
}
if
(
scd
.
getExternal
()
&&
!
""
.
equals
(
scd
.
getLicense
()))
{
String
license
=
scd
.
getLicense
();
HTML
viewLicenseHTML
=
new
HTML
(
"<a href=\""
+
license
+
"\" target=\"_blank\">"
+
MESSAGES
.
viewLicense
()
+
"</a>"
);
viewLicenseHTML
.
setStyleName
(
"ode-ComponentHelpPopup-Link"
);
inner
.
add
(
viewLicenseHTML
);
}
setWidget
(
inner
);
...
...
appinventor/appengine/src/com/google/appinventor/client/editor/simple/palette/SimpleComponentDescriptor.java
View file @
713ff82b
...
...
@@ -318,6 +318,18 @@ public final class SimpleComponentDescriptor {
return
dateBuilt
;
}
/**
* Returns the path to the license file used by the component.
*
* @return path to license file of component
*/
public
String
getLicense
()
{
String
type
=
COMPONENT_DATABASE
.
getComponentType
(
name
);
return
getLicenseURLFromPath
(
COMPONENT_DATABASE
.
getLicenseName
(
name
),
type
.
substring
(
0
,
type
.
lastIndexOf
(
'.'
)),
editor
.
getProjectId
());
}
/**
* Returns a draggable image for the component. Used when dragging a
* component from the palette onto the form.
...
...
@@ -370,6 +382,20 @@ public final class SimpleComponentDescriptor {
}
}
public
static
String
getLicenseURLFromPath
(
String
licensePath
,
String
packageName
,
long
projectId
)
{
if
(
licensePath
.
startsWith
(
"aiwebres/"
)
&&
packageName
!=
null
)
{
// License file is inside aiwebres
return
StorageUtil
.
getFileUrl
(
projectId
,
"assets/external_comps/"
+
packageName
+
"/"
+
licensePath
)
+
"&inline"
;
}
else
if
(
licensePath
.
startsWith
(
"http:"
)
||
licensePath
.
startsWith
(
"https:"
))
{
// The license is an external URL
return
licensePath
;
}
else
{
// No license file specified
return
""
;
}
}
/**
* Instantiates mock component by name.
*/
...
...
appinventor/appengine/src/com/google/appinventor/server/DownloadServlet.java
View file @
713ff82b
...
...
@@ -244,7 +244,9 @@ public class DownloadServlet extends OdeServlet {
// Set http response information
resp
.
setStatus
(
HttpServletResponse
.
SC_OK
);
resp
.
setHeader
(
"content-disposition"
,
"attachment; filename=\""
+
fileName
+
"\""
);
resp
.
setHeader
(
"content-disposition"
,
req
.
getParameter
(
"inline"
)
!=
null
?
"inline"
:
"attachment"
+
"; filename=\""
+
fileName
+
"\""
);
resp
.
setContentType
(
StorageUtil
.
getContentTypeForFilePath
(
fileName
));
resp
.
setContentLength
(
content
.
length
);
...
...
appinventor/appengine/src/com/google/appinventor/shared/simple/ComponentDatabaseInterface.java
View file @
713ff82b
...
...
@@ -43,11 +43,13 @@ public interface ComponentDatabaseInterface {
private
final
Map
<
String
,
String
>
propertiesTypesByName
;
private
final
boolean
nonVisible
;
private
final
String
iconName
;
private
final
String
licenseName
;
private
final
String
typeDescription
;
public
ComponentDefinition
(
String
name
,
int
version
,
String
versionName
,
String
dateBuilt
,
String
type
,
boolean
external
,
String
categoryString
,
String
helpString
,
String
helpUrl
,
boolean
showOnPalette
,
boolean
nonVisible
,
String
iconName
,
String
typeDescription
)
{
boolean
showOnPalette
,
boolean
nonVisible
,
String
iconName
,
String
licenseName
,
String
typeDescription
)
{
this
.
name
=
name
;
this
.
version
=
version
;
this
.
versionName
=
versionName
;
...
...
@@ -66,6 +68,7 @@ public interface ComponentDatabaseInterface {
this
.
propertiesTypesByName
=
new
HashMap
<
String
,
String
>();
this
.
nonVisible
=
nonVisible
;
this
.
iconName
=
iconName
;
this
.
licenseName
=
licenseName
;
this
.
typeDescription
=
typeDescription
;
}
...
...
@@ -156,6 +159,10 @@ public interface ComponentDatabaseInterface {
return
iconName
;
}
public
String
getLicenseName
()
{
return
licenseName
;
}
public
String
getTypeDescription
()
{
return
typeDescription
;
}
...
...
@@ -461,6 +468,12 @@ public interface ComponentDatabaseInterface {
*/
String
getIconName
(
String
componentName
);
/**
* Returns the name of the license file used by the component. Intended for use
* by external components.
*/
String
getLicenseName
(
String
componentName
);
/**
* Returns a list of a component's property definitions.
*
...
...
appinventor/components/src/com/google/appinventor/components/annotations/DesignerComponent.java
View file @
713ff82b
...
...
@@ -102,4 +102,14 @@ public @interface DesignerComponent {
* the component.
*/
String
dateBuilt
()
default
""
;
/**
* The file name of the LICENSE file that the component is attributed under.
* Meant primarily for use by external components which can have a license
* different from that of this codebase. This string can also be a URL pointing
* to an external LICENSE file.
*
* @return The name of the LICENSE file
*/
String
licenseName
()
default
""
;
}
appinventor/components/src/com/google/appinventor/components/scripts/ComponentDescriptorGenerator.java
View file @
713ff82b
...
...
@@ -35,6 +35,7 @@ import javax.tools.FileObject;
* "showOnPalette": "true"|"false",
* "nonVisible": "true"|"false",
* "iconName": "ICON-FILE-NAME",
* "licenseName": "LICENSE-FILE-NAME",
* "androidMinSdk": "ANDROID-MIN-SDK",
* "conditionals": {
* "permissions": {
...
...
@@ -109,6 +110,8 @@ public final class ComponentDescriptorGenerator extends ComponentProcessor {
sb
.
append
(
component
.
getNonVisible
());
sb
.
append
(
"\",\n \"iconName\": \""
);
sb
.
append
(
component
.
getIconName
());
sb
.
append
(
"\",\n \"licenseName\": \""
);
sb
.
append
(
component
.
getLicenseName
());
sb
.
append
(
"\",\n \"androidMinSdk\": "
);
sb
.
append
(
component
.
getAndroidMinSdk
());
outputConditionalAnnotations
(
component
,
sb
);
...
...
@@ -213,8 +216,8 @@ public final class ComponentDescriptorGenerator extends ComponentProcessor {
*/
private
void
outputConditionalAnnotations
(
ComponentInfo
component
,
StringBuilder
sb
)
{
if
(
component
.
conditionalPermissions
.
size
()
+
component
.
conditionalBroadcastReceivers
.
size
()
+
component
.
conditionalServices
.
size
()
+
component
.
conditionalBroadcastReceivers
.
size
()
+
component
.
conditionalServices
.
size
()
+
component
.
conditionalContentProviders
.
size
()
==
0
)
{
return
;
}
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
View file @
713ff82b
...
...
@@ -717,7 +717,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
* Content providers required by this component.
*/
protected
final
Set
<
String
>
contentProviders
;
/**
* TODO(Will): Remove the following field once the deprecated {@link SimpleBroadcastReceiver}
* annotation is removed. It should should remain for the time being
...
...
@@ -780,6 +780,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
private
int
androidMinSdk
;
private
String
versionName
;
private
String
dateBuilt
;
private
String
licenseName
;
protected
ComponentInfo
(
Element
element
)
{
super
(
element
.
getSimpleName
().
toString
(),
// Short name
...
...
@@ -869,6 +870,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
showOnPalette
=
designerComponentAnnotation
.
showOnPalette
();
nonVisible
=
designerComponentAnnotation
.
nonVisible
();
iconName
=
designerComponentAnnotation
.
iconName
();
licenseName
=
designerComponentAnnotation
.
licenseName
();
androidMinSdk
=
designerComponentAnnotation
.
androidMinSdk
();
versionName
=
designerComponentAnnotation
.
versionName
();
userVisible
=
designerComponentAnnotation
.
showOnPalette
();
...
...
@@ -989,6 +991,16 @@ public abstract class ComponentProcessor extends AbstractProcessor {
return
dateBuilt
;
}
/**
* Returns the name of the license file used by external components
* {@link DesignerComponent#licenseName()}.
*
* @return the name of the license file
*/
protected
String
getLicenseName
()
{
return
licenseName
;
}
private
String
getDisplayNameForComponentType
(
String
componentTypeName
)
{
// Users don't know what a 'Form' is. They know it as a 'Screen'.
return
"Form"
.
equals
(
componentTypeName
)
?
"Screen"
:
componentTypeName
;
...
...
@@ -1328,7 +1340,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
throw
new
RuntimeException
(
e
);
}
}
// TODO(Will): Remove the following legacy code once the deprecated
// @SimpleBroadcastReceiver annotation is removed. It should
// should remain for the time being because otherwise we'll break
...
...
@@ -1338,7 +1350,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
// has a Class Name and zero or more Filter Actions. In the
// resulting String, Class name will go first, and each Action
// will be added, separated by a comma.
SimpleBroadcastReceiver
simpleBroadcastReceiver
=
element
.
getAnnotation
(
SimpleBroadcastReceiver
.
class
);
if
(
simpleBroadcastReceiver
!=
null
)
{
for
(
String
className
:
simpleBroadcastReceiver
.
className
().
split
(
","
)){
...
...
@@ -1555,7 +1567,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
StringBuilder
elementString
=
new
StringBuilder
(
" <intent-filter "
);
elementString
.
append
(
elementAttributesToString
(
element
));
elementString
.
append
(
">\\n"
);
// Now, we collect any <intent-filter> subelements.
elementString
.
append
(
subelementsToString
(
element
.
actionElements
()));
elementString
.
append
(
subelementsToString
(
element
.
categoryElements
()));
...
...
@@ -1657,7 +1669,7 @@ public abstract class ComponentProcessor extends AbstractProcessor {
}
return
attributeString
.
toString
();
}
// Build the subelement String for a given array of XML elements modeled by
// corresponding annotations.
private
static
String
subelementsToString
(
Annotation
[]
subelements
)
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ExternalComponentGenerator.java
View file @
713ff82b
...
...
@@ -106,6 +106,7 @@ public class ExternalComponentGenerator {
generateExternalComponentDescriptors
(
name
,
entry
.
getValue
());
for
(
ExternalComponentInfo
info
:
entry
.
getValue
())
{
copyIcon
(
name
,
info
.
descriptor
);
copyLicense
(
name
,
info
.
descriptor
);
copyAssets
(
name
,
info
.
descriptor
);
}
generateExternalComponentBuildFiles
(
name
,
entry
.
getValue
());
...
...
@@ -230,6 +231,26 @@ public class ExternalComponentGenerator {
}
}
private
static
void
copyLicense
(
String
packageName
,
JSONObject
componentDescriptor
)
throws
IOException
,
JSONException
{
String
license
=
componentDescriptor
.
getString
(
"licenseName"
);
if
(
""
.
equals
(
license
)
||
license
.
startsWith
(
"http:"
)
||
license
.
startsWith
(
"https:"
))
{
// License will be loaded from the web
return
;
}
String
packagePath
=
packageName
.
replace
(
'.'
,
File
.
separatorChar
);
File
sourceDir
=
new
File
(
externalComponentsDirPath
+
File
.
separator
+
".."
+
File
.
separator
+
".."
+
File
.
separator
+
"src"
+
File
.
separator
+
packagePath
);
File
licenseFile
=
new
File
(
sourceDir
,
license
);
if
(
licenseFile
.
exists
())
{
File
destinationLicense
=
new
File
(
externalComponentsDirPath
+
File
.
separator
+
packageName
+
File
.
separator
+
license
);
ensureDirectory
(
destinationLicense
.
getParent
(),
"Unable to create directory "
+
destinationLicense
.
getParent
());
System
.
out
.
println
(
"Extensions : "
+
"Copying file "
+
licenseFile
.
getAbsolutePath
());
copyFile
(
licenseFile
.
getAbsolutePath
(),
destinationLicense
.
getAbsolutePath
());
}
else
{
System
.
out
.
println
(
"Extensions : Skipping missing license "
+
license
);
}
}
private
static
void
copyAssets
(
String
packageName
,
JSONObject
componentDescriptor
)
throws
IOException
,
JSONException
{
JSONArray
assets
=
componentDescriptor
.
optJSONArray
(
"assets"
);
...
...
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