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
6aa70536
Commit
6aa70536
authored
Jun 19, 2018
by
Evan W. Patton
Committed by
Jeffrey Schiller
Jun 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement UsesAssets support for extensions
Change-Id: Id0995d95294c4e604b17eebf495f3ee04b87c36d
parent
a8f5b679
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
208 additions
and
35 deletions
+208
-35
appinventor/appengine/src/com/google/appinventor/client/AssetManager.java
...ngine/src/com/google/appinventor/client/AssetManager.java
+8
-2
appinventor/buildserver/build.xml
appinventor/buildserver/build.xml
+2
-0
appinventor/buildserver/src/com/google/appinventor/buildserver/Compiler.java
...rver/src/com/google/appinventor/buildserver/Compiler.java
+33
-11
appinventor/components/src/com/google/appinventor/components/runtime/Form.java
...s/src/com/google/appinventor/components/runtime/Form.java
+42
-0
appinventor/components/src/com/google/appinventor/components/runtime/ReplForm.java
...c/com/google/appinventor/components/runtime/ReplForm.java
+53
-16
appinventor/components/src/com/google/appinventor/components/runtime/util/NativeOpenStreetMapController.java
...omponents/runtime/util/NativeOpenStreetMapController.java
+1
-1
appinventor/components/src/com/google/appinventor/components/scripts/ComponentDescriptorGenerator.java
...ntor/components/scripts/ComponentDescriptorGenerator.java
+16
-3
appinventor/components/src/com/google/appinventor/components/scripts/ExternalComponentGenerator.java
...ventor/components/scripts/ExternalComponentGenerator.java
+53
-2
appinventor/components/tests/assets/marker.svg
appinventor/components/tests/assets/marker.svg
+0
-0
No files found.
appinventor/appengine/src/com/google/appinventor/client/AssetManager.java
View file @
6aa70536
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-201
7
MIT, All rights reserved
// Copyright 2011-201
8
MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
...
...
@@ -172,13 +172,19 @@ public final class AssetManager implements ProjectChangeListener {
allow
=
false
;
// Filter : For files in directly in EXTERNAL_COMPS_FOLDER/COMP_FOLDER
if
(
StringUtils
.
countMatches
(
fileId
,
"/"
)
==
3
)
{
int
depth
=
StringUtils
.
countMatches
(
fileId
,
"/"
);
if
(
depth
==
3
)
{
// Filter : For classes.jar File
if
(
name
.
equals
(
"classes.jar"
))
{
allow
=
true
;
}
}
else
if
(
depth
>
3
)
{
String
[]
parts
=
fileId
.
split
(
"/"
);
if
(
ASSETS_FOLDER
.
equals
(
parts
[
3
]))
{
return
true
;
}
}
}
}
...
...
appinventor/buildserver/build.xml
View file @
6aa70536
...
...
@@ -68,6 +68,8 @@
<!-- Map assets for build server -->
<fileset
dir=
"${lib.dir}/leaflet"
includes=
"leaflet.js,leaflet.css"
/>
<fileset
dir=
"${lib.dir}/leaflet/assets"
includes=
"*"
/>
<!-- Component/extension assets (for testing) -->
<fileset
dir=
"${appinventor.dir}/components/src"
includes=
"**/assets/*"
/>
</copy>
<copy
toFile=
"${classes.files.dir}/osmdroid.aar"
file=
"${lib.dir}/osmdroid/osmdroid-5.6.6.aar"
/>
<copy
toFile=
"${classes.files.dir}/osmdroid.jar"
file=
"${lib.dir}/osmdroid/osmdroid-5.6.6.jar"
/>
...
...
appinventor/buildserver/src/com/google/appinventor/buildserver/Compiler.java
View file @
6aa70536
...
...
@@ -114,6 +114,7 @@ public final class Compiler {
private
static
final
String
ARMEABI_DIR_NAME
=
"armeabi"
;
private
static
final
String
ARMEABI_V7A_DIR_NAME
=
"armeabi-v7a"
;
private
static
final
String
ASSET_DIR_NAME
=
"assets"
;
private
static
final
String
EXT_COMPS_DIR_NAME
=
"external_comps"
;
private
static
final
String
DEFAULT_APP_NAME
=
""
;
...
...
@@ -1467,7 +1468,7 @@ public final class Compiler {
private
boolean
runAaptPackage
(
File
manifestFile
,
File
resDir
,
String
tmpPackageName
,
File
sourceOutputDir
,
File
symbolOutputDir
)
{
// Need to make sure assets directory exists otherwise aapt will fail.
createDir
(
project
.
getAssetsDirectory
()
);
final
File
mergedAssetsDir
=
createDir
(
project
.
getBuildDirectory
(),
ASSET_DIR_NAME
);
String
aaptTool
;
String
osName
=
System
.
getProperty
(
"os.name"
);
if
(
osName
.
equals
(
"Mac OS X"
))
{
...
...
@@ -1498,7 +1499,7 @@ public final class Compiler {
aaptPackageCommandLineArgs
.
add
(
"-S"
);
aaptPackageCommandLineArgs
.
add
(
mergedResDir
.
getAbsolutePath
());
aaptPackageCommandLineArgs
.
add
(
"-A"
);
aaptPackageCommandLineArgs
.
add
(
project
.
getAssetsDirectory
()
.
getAbsolutePath
());
aaptPackageCommandLineArgs
.
add
(
mergedAssetsDir
.
getAbsolutePath
());
aaptPackageCommandLineArgs
.
add
(
"-I"
);
aaptPackageCommandLineArgs
.
add
(
getResource
(
ANDROID_RUNTIME
));
aaptPackageCommandLineArgs
.
add
(
"-F"
);
...
...
@@ -1619,25 +1620,28 @@ public final class Compiler {
}
private
boolean
attachCompAssets
()
{
createDir
(
project
.
get
Assets
Directory
());
// Needed to insert resources.
createDir
(
project
.
get
Build
Directory
());
// Needed to insert resources.
try
{
// Gather non-library assets to be added to apk's Asset directory.
// The assets directory have been created before this.
File
compAssetDir
=
createDir
(
project
.
getAssetsDirectory
(),
ASSET_DIRECTORY
);
File
mergedAssetDir
=
createDir
(
project
.
getBuildDirectory
(),
ASSET_DIR_NAME
);
// Copy component/extension assets to build/assets
for
(
String
type
:
assetsNeeded
.
keySet
())
{
for
(
String
assetName
:
assetsNeeded
.
get
(
type
))
{
File
targetDir
=
compAssetDir
;
String
sourcePath
=
""
;
String
pathSuffix
=
RUNTIME_FILES_DIR
+
assetName
;
File
targetDir
=
mergedAssetDir
;
String
sourcePath
;
if
(
simpleCompTypes
.
contains
(
type
))
{
String
pathSuffix
=
RUNTIME_FILES_DIR
+
assetName
;
sourcePath
=
getResource
(
pathSuffix
);
}
else
if
(
extCompTypes
.
contains
(
type
))
{
sourcePath
=
getExtCompDirPath
(
type
)
+
pathSuffix
;
targetDir
=
createDir
(
targetDir
,
EXT_COMPS_DIR_NAME
);
targetDir
=
createDir
(
targetDir
,
type
);
final
String
extCompDir
=
getExtCompDirPath
(
type
);
sourcePath
=
getExtAssetPath
(
extCompDir
,
assetName
);
// If targetDir's location is changed here, you must update Form.java in components to
// reference the new location. The path for assets in compiled apps is assumed to be
// assets/EXTERNAL-COMP-PACKAGE/ASSET-NAME
targetDir
=
createDir
(
targetDir
,
basename
(
extCompDir
));
}
else
{
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Assets"
));
return
false
;
...
...
@@ -1646,6 +1650,16 @@ public final class Compiler {
Files
.
copy
(
new
File
(
sourcePath
),
new
File
(
targetDir
,
assetName
));
}
}
// Copy project assets to build/assets
File
[]
assets
=
project
.
getAssetsDirectory
().
listFiles
();
if
(
assets
!=
null
)
{
for
(
File
asset
:
assets
)
{
if
(
asset
.
isFile
())
{
Files
.
copy
(
asset
,
new
File
(
mergedAssetDir
,
asset
.
getName
()));
}
}
}
return
true
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
...
...
@@ -1958,4 +1972,12 @@ public final class Compiler {
}
throw
new
IllegalStateException
(
"Project lacks extension directory for "
+
type
);
}
private
static
String
basename
(
String
path
)
{
return
new
File
(
path
).
getName
();
}
private
static
String
getExtAssetPath
(
String
extCompDir
,
String
assetName
)
{
return
extCompDir
+
File
.
separator
+
ASSET_DIR_NAME
+
File
.
separator
+
assetName
;
}
}
appinventor/components/src/com/google/appinventor/components/runtime/Form.java
View file @
6aa70536
...
...
@@ -6,15 +6,21 @@
package
com.google.appinventor.components.runtime
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
android.content.res.AssetManager
;
import
android.support.v7.app.ActionBar
;
import
android.app.Activity
;
import
android.app.Dialog
;
...
...
@@ -109,6 +115,8 @@ public class Form extends AppInventorCompatActivity
public
static
final
String
APPINVENTOR_URL_SCHEME
=
"appinventor"
;
public
static
final
String
ASSETS_PREFIX
=
"file:///android_asset/"
;
private
static
final
int
DEFAULT_PRIMARY_COLOR_DARK
=
PaintUtil
.
hexStringToInt
(
ComponentConstants
.
DEFAULT_PRIMARY_DARK_COLOR
);
private
static
final
int
DEFAULT_ACCENT_COLOR
=
PaintUtil
.
hexStringToInt
(
ComponentConstants
.
DEFAULT_ACCENT_COLOR
);
...
...
@@ -2273,4 +2281,38 @@ public class Form extends AppInventorCompatActivity
public
boolean
isDarkTheme
()
{
return
usesDarkTheme
;
}
/**
* Determines a WebView compatible, REPL-sensitive path for an asset provided by a given
* extension.
*
* @param component The extension that is requesting an asset
* @param asset The asset filename
* @return A string containing the path to the asset
* @throws FileNotFoundException if the asset cannot be located
*/
public
String
getAssetPathForExtension
(
Component
component
,
String
asset
)
throws
FileNotFoundException
{
String
extPkgName
=
component
.
getClass
().
getPackage
().
getName
();
return
ASSETS_PREFIX
+
extPkgName
+
"/"
+
asset
;
}
/**
* Opens an asset for reading as an InputStream. If the asset cannot be found, an IOException will
* be raised.
*
* @param component The extension that is requesting an asset
* @param asset The asset filename
* @return A new input stream for the requested asset. The caller is responsible for closing the
* stream to prevent resource leaking.
* @throws IOException if the asset is not found or cannot be read
*/
public
InputStream
openAssetForExtension
(
Component
component
,
String
asset
)
throws
IOException
{
String
path
=
getAssetPathForExtension
(
component
,
asset
);
if
(
path
.
startsWith
(
ASSETS_PREFIX
))
{
final
AssetManager
am
=
getAssets
();
return
am
.
open
(
path
.
substring
(
ASSETS_PREFIX
.
length
()));
}
else
{
return
new
FileInputStream
(
new
File
(
URI
.
create
(
path
)));
}
}
}
appinventor/components/src/com/google/appinventor/components/runtime/ReplForm.java
View file @
6aa70536
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-201
2
MIT, All rights reserved
// Copyright 2011-201
8
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.runtime
;
import
java.io.FileNotFoundException
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.Iterator
;
...
...
@@ -26,6 +27,7 @@ import android.support.v7.internal.widget.TintImageView;
import
android.text.Html
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
com.google.appinventor.components.annotations.SimpleObject
;
import
com.google.appinventor.components.annotations.SimpleProperty
;
import
com.google.appinventor.components.common.ComponentConstants
;
import
com.google.appinventor.components.runtime.util.AppInvHTTPD
;
...
...
@@ -52,6 +54,7 @@ import android.widget.Toast;
public
class
ReplForm
extends
Form
{
private
static
final
String
LOG_TAG
=
ReplForm
.
class
.
getSimpleName
();
private
AppInvHTTPD
httpdServer
=
null
;
public
static
ReplForm
topform
;
private
static
final
String
REPL_ASSET_DIR
=
...
...
@@ -74,7 +77,7 @@ public class ReplForm extends Form {
@Override
public
void
onCreate
(
Bundle
icicle
)
{
super
.
onCreate
(
icicle
);
Log
.
d
(
"ReplForm"
,
"onCreate"
);
Log
.
d
(
LOG_TAG
,
"onCreate"
);
loadedExternalDexs
=
new
ArrayList
<
String
>();
Intent
intent
=
getIntent
();
processExtras
(
intent
,
false
);
...
...
@@ -115,7 +118,7 @@ public class ReplForm extends Form {
public
void
setFormName
(
String
formName
)
{
this
.
formName
=
formName
;
Log
.
d
(
"ReplForm"
,
"formName is now "
+
formName
);
Log
.
d
(
LOG_TAG
,
"formName is now "
+
formName
);
}
@Override
...
...
@@ -124,7 +127,7 @@ public class ReplForm extends Form {
}
protected
void
setResult
(
Object
result
)
{
Log
.
d
(
"ReplForm"
,
"setResult: "
+
result
);
Log
.
d
(
LOG_TAG
,
"setResult: "
+
result
);
replResult
=
result
;
replResultFormName
=
formName
;
}
...
...
@@ -186,15 +189,15 @@ public class ReplForm extends Form {
@Override
protected
void
onNewIntent
(
Intent
intent
)
{
super
.
onNewIntent
(
intent
);
Log
.
d
(
"ReplForm"
,
"onNewIntent Called"
);
Log
.
d
(
LOG_TAG
,
"onNewIntent Called"
);
processExtras
(
intent
,
true
);
}
void
HandleReturnValues
()
{
Log
.
d
(
"ReplForm"
,
"HandleReturnValues() Called, replResult = "
+
replResult
);
Log
.
d
(
LOG_TAG
,
"HandleReturnValues() Called, replResult = "
+
replResult
);
if
(
replResult
!=
null
)
{
// Act as if it was returned
OtherScreenClosed
(
replResultFormName
,
replResult
);
Log
.
d
(
"ReplForm"
,
"Called OtherScreenClosed"
);
Log
.
d
(
LOG_TAG
,
"Called OtherScreenClosed"
);
replResult
=
null
;
}
}
...
...
@@ -202,14 +205,14 @@ public class ReplForm extends Form {
protected
void
processExtras
(
Intent
intent
,
boolean
restart
)
{
Bundle
extras
=
intent
.
getExtras
();
if
(
extras
!=
null
)
{
Log
.
d
(
"ReplForm"
,
"extras: "
+
extras
);
Log
.
d
(
LOG_TAG
,
"extras: "
+
extras
);
Iterator
<
String
>
keys
=
extras
.
keySet
().
iterator
();
while
(
keys
.
hasNext
())
{
Log
.
d
(
"ReplForm"
,
"Extra Key: "
+
keys
.
next
());
Log
.
d
(
LOG_TAG
,
"Extra Key: "
+
keys
.
next
());
}
}
if
((
extras
!=
null
)
&&
extras
.
getBoolean
(
"rundirect"
))
{
Log
.
d
(
"ReplForm"
,
"processExtras rundirect is true and restart is "
+
restart
);
Log
.
d
(
LOG_TAG
,
"processExtras rundirect is true and restart is "
+
restart
);
isDirect
=
true
;
assetsLoaded
=
true
;
if
(
restart
)
{
...
...
@@ -238,10 +241,10 @@ public class ReplForm extends Form {
if
(
httpdServer
==
null
)
{
checkAssetDir
();
httpdServer
=
new
AppInvHTTPD
(
8001
,
new
File
(
REPL_ASSET_DIR
),
secure
,
this
);
// Probably should make the port variable
Log
.
i
(
"ReplForm"
,
"started AppInvHTTPD"
);
Log
.
i
(
LOG_TAG
,
"started AppInvHTTPD"
);
}
}
catch
(
IOException
ex
)
{
Log
.
e
(
"ReplForm"
,
"Setting up NanoHTTPD: "
+
ex
.
toString
());
Log
.
e
(
LOG_TAG
,
"Setting up NanoHTTPD: "
+
ex
.
toString
());
}
}
...
...
@@ -283,7 +286,7 @@ public class ReplForm extends Form {
File
dexOutput
=
activeForm
.
$context
().
getDir
(
"componentDexs"
,
Context
.
MODE_PRIVATE
);
File
componentFolder
=
new
File
(
REPL_COMP_DIR
);
if
(!
checkComponentDir
())
{
Log
.
d
(
"ReplForm"
,
"Unable to create components directory"
);
Log
.
d
(
LOG_TAG
,
"Unable to create components directory"
);
dispatchErrorOccurredEventDialog
(
this
,
"loadComponents"
,
ErrorMessages
.
ERROR_EXTENSION_ERROR
,
1
,
"App Inventor"
,
"Unable to create component directory."
);
return
;
...
...
@@ -299,7 +302,7 @@ public class ReplForm extends Form {
File
loadComponent
=
new
File
(
compFolder
.
getPath
()
+
File
.
separator
+
compFolder
.
getName
()
+
".jar"
);
component
.
renameTo
(
loadComponent
);
if
(
loadComponent
.
exists
()
&&
!
loadedExternalDexs
.
contains
(
loadComponent
.
getName
()))
{
Log
.
d
(
"ReplForm"
,
"Loading component dex "
+
loadComponent
.
getAbsolutePath
());
Log
.
d
(
LOG_TAG
,
"Loading component dex "
+
loadComponent
.
getAbsolutePath
());
loadedExternalDexs
.
add
(
loadComponent
.
getName
());
sb
.
append
(
File
.
pathSeparatorChar
);
sb
.
append
(
loadComponent
.
getAbsolutePath
());
...
...
@@ -309,8 +312,8 @@ public class ReplForm extends Form {
DexClassLoader
dexCloader
=
new
DexClassLoader
(
sb
.
substring
(
1
),
dexOutput
.
getAbsolutePath
(),
null
,
parentClassLoader
);
Thread
.
currentThread
().
setContextClassLoader
(
dexCloader
);
Log
.
d
(
"ReplForm"
,
Thread
.
currentThread
().
toString
());
Log
.
d
(
"ReplForm"
,
Looper
.
getMainLooper
().
getThread
().
toString
());
Log
.
d
(
LOG_TAG
,
Thread
.
currentThread
().
toString
());
Log
.
d
(
LOG_TAG
,
Looper
.
getMainLooper
().
getThread
().
toString
());
Looper
.
getMainLooper
().
getThread
().
setContextClassLoader
(
dexCloader
);
}
...
...
@@ -322,6 +325,40 @@ public class ReplForm extends Form {
updateTitle
();
}
@Override
public
String
getAssetPathForExtension
(
Component
component
,
String
asset
)
throws
FileNotFoundException
{
// For testing extensions, we allow external = false, but still compile the assets into the
// companion for testing. When external = true, we are assuming this is an extension loaded
// into the production companion.
SimpleObject
annotation
=
component
.
getClass
().
getAnnotation
(
SimpleObject
.
class
);
if
(
annotation
!=
null
&&
!
annotation
.
external
())
{
return
ASSETS_PREFIX
+
asset
;
}
String
extensionId
=
component
.
getClass
().
getName
();
String
pkgPath
=
null
;
while
(
extensionId
.
contains
(
"."
))
{
File
dir
=
new
File
(
REPL_COMP_DIR
+
extensionId
+
"/assets"
);
if
(
dir
.
exists
()
&&
dir
.
isDirectory
())
{
// found the extension directory
pkgPath
=
dir
.
getAbsolutePath
();
break
;
}
// Walk up the FQCN to determine possible extension identifier
extensionId
=
extensionId
.
substring
(
0
,
extensionId
.
lastIndexOf
(
'.'
));
}
if
(
pkgPath
!=
null
)
{
File
result
=
new
File
(
pkgPath
,
asset
);
Log
.
d
(
LOG_TAG
,
"result = "
+
result
.
getAbsolutePath
());
if
(
result
.
exists
())
{
return
"file://"
+
result
.
getAbsolutePath
();
}
}
throw
new
FileNotFoundException
();
}
@Override
protected
boolean
isRepl
()
{
return
true
;
...
...
appinventor/components/src/com/google/appinventor/components/runtime/util/NativeOpenStreetMapController.java
View file @
6aa70536
...
...
@@ -906,7 +906,7 @@ class NativeOpenStreetMapController implements MapController, MapListener {
SVG
markerSvg
=
null
;
if
(
defaultMarkerSVG
==
null
)
{
try
{
defaultMarkerSVG
=
SVG
.
getFromAsset
(
view
.
getContext
().
getAssets
(),
"
component/
marker.svg"
);
defaultMarkerSVG
=
SVG
.
getFromAsset
(
view
.
getContext
().
getAssets
(),
"marker.svg"
);
}
catch
(
SVGParseException
e
)
{
Log
.
e
(
TAG
,
"Invalid SVG in Marker asset"
,
e
);
}
catch
(
IOException
e
)
{
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentDescriptorGenerator.java
View file @
6aa70536
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-201
7
MIT, All rights reserved
// Copyright 2011-201
8
MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
...
...
@@ -59,7 +59,8 @@ import javax.tools.FileObject;
* { "name": "PARAM-NAME",
* "type": "YAIL-TYPE"},*
* ]},+
* ]
* ],
* ("assets": ["FILENAME",*])?
* }
*
* @author lizlooney@google.com (Liz Looney)
...
...
@@ -130,7 +131,19 @@ public final class ComponentDescriptorGenerator extends ComponentProcessor {
outputBlockMethod
(
method
.
name
,
method
,
sb
,
method
.
userVisible
,
method
.
deprecated
);
separator
=
",\n "
;
}
sb
.
append
(
"]}\n"
);
sb
.
append
(
"]"
);
// Output assets for extensions (consumed by ExternalComponentGenerator and buildserver)
if
(
component
.
external
&&
component
.
assets
.
size
()
>
0
)
{
sb
.
append
(
",\n \"assets\": ["
);
for
(
String
asset
:
component
.
assets
)
{
sb
.
append
(
"\""
);
sb
.
append
(
asset
.
replaceAll
(
"\\\\"
,
"\\\\"
).
replaceAll
(
"\""
,
"\\\""
));
sb
.
append
(
"\","
);
}
sb
.
setLength
(
sb
.
length
()
-
1
);
sb
.
append
(
"]"
);
}
sb
.
append
(
"}\n"
);
}
private
void
outputProperty
(
String
propertyName
,
DesignerProperty
dp
,
StringBuilder
sb
)
{
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ExternalComponentGenerator.java
View file @
6aa70536
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2015 MIT, All rights reserved
// Copyright 2015
-2018
MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
...
...
@@ -9,7 +9,6 @@ import java.io.FileInputStream;
import
java.io.FileOutputStream
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.io.FileNotFoundException
;
import
java.nio.charset.Charset
;
import
java.nio.file.Files
;
import
java.nio.file.Paths
;
...
...
@@ -109,6 +108,7 @@ public class ExternalComponentGenerator {
generateExternalComponentDescriptors
(
name
,
entry
.
getValue
());
for
(
ExternalComponentInfo
info
:
entry
.
getValue
())
{
copyIcon
(
name
,
info
.
type
,
info
.
descriptor
);
copyAssets
(
name
,
info
.
type
,
info
.
descriptor
);
}
generateExternalComponentBuildFiles
(
name
,
entry
.
getValue
());
generateExternalComponentOtherFiles
(
name
);
...
...
@@ -230,6 +230,42 @@ public class ExternalComponentGenerator {
}
}
private
static
void
copyAssets
(
String
packageName
,
String
type
,
JSONObject
componentDescriptor
)
throws
IOException
,
JSONException
{
JSONArray
assets
=
componentDescriptor
.
optJSONArray
(
"assets"
);
if
(
assets
==
null
)
{
return
;
}
// Get asset source directory
String
packagePath
=
packageName
.
replace
(
'.'
,
File
.
separatorChar
);
File
sourceDir
=
new
File
(
externalComponentsDirPath
+
File
.
separator
+
".."
+
File
.
separator
+
".."
+
File
.
separator
+
"src"
+
File
.
separator
+
packagePath
);
File
assetSrcDir
=
new
File
(
sourceDir
,
"assets"
);
if
(!
assetSrcDir
.
exists
()
||
!
assetSrcDir
.
isDirectory
())
{
return
;
}
// Get asset dest directory
File
destDir
=
new
File
(
externalComponentsDirPath
+
File
.
separator
+
packageName
+
File
.
separator
);
File
assetDestDir
=
new
File
(
destDir
,
"assets"
);
if
(
assetDestDir
.
exists
()
&&
!
deleteRecursively
(
assetDestDir
))
{
throw
new
IllegalStateException
(
"Unable to delete the assets directory for the extension."
);
}
if
(!
assetDestDir
.
mkdirs
())
{
throw
new
IllegalStateException
(
"Unable to create the assets directory for the extension."
);
}
// Copy assets
for
(
int
i
=
0
;
i
<
assets
.
length
();
i
++)
{
String
asset
=
assets
.
getString
(
i
);
if
(!
asset
.
isEmpty
())
{
if
(!
copyFile
(
assetSrcDir
.
getAbsolutePath
()
+
File
.
separator
+
asset
,
assetDestDir
.
getAbsolutePath
()
+
File
.
separator
+
asset
))
{
throw
new
IllegalStateException
(
"Unable to copy asset to destination."
);
}
}
}
}
private
static
void
generateExternalComponentOtherFiles
(
String
packageName
)
throws
IOException
{
String
extensionDirPath
=
externalComponentsDirPath
+
File
.
separator
+
packageName
;
...
...
@@ -346,5 +382,20 @@ public class ExternalComponentGenerator {
return
componentPackage
;
}
private
static
boolean
deleteRecursively
(
File
dirOrFile
)
{
if
(
dirOrFile
.
isFile
())
{
return
dirOrFile
.
delete
();
}
else
{
boolean
result
=
true
;
File
[]
children
=
dirOrFile
.
listFiles
();
if
(
children
!=
null
)
{
for
(
File
child
:
children
)
{
result
=
result
&&
deleteRecursively
(
child
);
}
}
return
result
&&
dirOrFile
.
delete
();
}
}
}
appinventor/components/tests/assets/
component/
marker.svg
→
appinventor/components/tests/assets/marker.svg
View file @
6aa70536
File moved
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