use of com.codename1.rad.processing.Result in project CodenameOne by codenameone.
the class Table method getPropertyValue.
/**
* {@inheritDoc}
*/
public Object getPropertyValue(String name) {
if (name.equals("data")) {
String[][] result = new String[((DefaultTableModel) model).data.size()][];
for (int iter = 0; iter < result.length; iter++) {
Object[] o = ((DefaultTableModel) model).data.get(iter);
String[] arr = new String[o.length];
result[iter] = arr;
for (int ai = 0; ai < arr.length; ai++) {
Object current = o[ai];
if (current instanceof String) {
arr[ai] = (String) current;
} else {
if (current != null) {
arr[iter] = current.toString();
}
}
}
}
return result;
}
if (name.equals("header")) {
return ((DefaultTableModel) model).columnNames;
}
return null;
}
use of com.codename1.rad.processing.Result in project CodenameOne by codenameone.
the class JavaSEPort method getProjectBuildHints.
@Override
public Map<String, String> getProjectBuildHints() {
File cnopFile = new File(getCWD(), "codenameone_settings.properties");
if (cnopFile.exists()) {
java.util.Properties cnop = new java.util.Properties();
try (InputStream is = new FileInputStream(cnopFile)) {
cnop.load(is);
} catch (IOException err) {
return null;
}
HashMap<String, String> result = new HashMap<>();
for (Object kk : cnop.keySet()) {
String key = (String) kk;
if (key.startsWith("codename1.arg.")) {
String val = cnop.getProperty(key);
key = key.substring(14);
result.put(key, val);
}
}
return Collections.unmodifiableMap(result);
}
return null;
}
use of com.codename1.rad.processing.Result in project CodenameOne by codenameone.
the class ConnectionRequest method fetchJSONAsync.
/**
* Fetches JSON asynchronously.
* @param url The URL to fetch.
* @return AsyncResource that will resolve with either an exception or the parsed JSON data.
* @since 7.0
*/
public static AsyncResource<Map<String, Object>> fetchJSONAsync(String url) {
final AsyncResource<Map<String, Object>> out = new AsyncResource<Map<String, Object>>();
final ConnectionRequest cr = new ConnectionRequest();
cr.setFailSilently(true);
cr.setPost(false);
cr.setUrl(url);
cr.addResponseListener(new ActionListener<NetworkEvent>() {
@Override
public void actionPerformed(NetworkEvent evt) {
if (out.isDone()) {
return;
}
if (cr.getResponseData() == null) {
if (cr.failureException != null) {
out.error(new IOException(cr.failureException.toString()));
return;
} else {
out.error(new IOException("Server returned error code: " + cr.failureErrorCode));
return;
}
}
JSONParser jp = new JSONParser();
Map<String, Object> result = null;
try {
result = jp.parseJSON(new InputStreamReader(new ByteArrayInputStream(cr.getResponseData()), "UTF-8"));
} catch (IOException ex) {
out.error(ex);
return;
}
out.complete(result);
}
});
NetworkManager.getInstance().addToQueue(cr);
return out;
}
use of com.codename1.rad.processing.Result in project CodenameOne by codenameone.
the class Util method getFileSizeWithoutDownload.
/**
* Returns -2 if the server doesn't accept partial downloads (and if
* checkPartialDownloadSupport is true), -1 if the content length is unknow,
* a value greater than 0 if the Content-Length is known.
*
* @param url
* @param checkPartialDownloadSupport if true returns -2 if the server
* doesn't accept partial downloads.
* @return Content-Length if known
*/
public static long getFileSizeWithoutDownload(final String url, final boolean checkPartialDownloadSupport) {
// documentation about the headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
// code discussed here: https://stackoverflow.com/a/62130371
final Wrapper<Long> result = new Wrapper<Long>(0l);
ConnectionRequest cr = new GZConnectionRequest() {
@Override
protected void readHeaders(Object connection) throws IOException {
String acceptRanges = getHeader(connection, "Accept-Ranges");
if (checkPartialDownloadSupport && (acceptRanges == null || !acceptRanges.equals("bytes"))) {
// Log.p("The partial downloads of " + url + " are not supported.", Log.WARNING);
result.set(-2l);
} else {
String contentLength = getHeader(connection, "Content-Length");
if (contentLength != null) {
result.set(Long.parseLong(contentLength));
} else {
// Log.p("The Content-Length of " + url + " is unknown.", Log.WARNING);
result.set(-1l);
}
}
}
};
cr.setUrl(url);
cr.setHttpMethod("HEAD");
cr.setPost(false);
NetworkManager.getInstance().addToQueueAndWait(cr);
return result.get();
}
use of com.codename1.rad.processing.Result in project CodenameOne by codenameone.
the class Util method downloadUrlSafely.
/**
* <p>
* Safely download the given URL to the Storage or to the FileSystemStorage:
* this method is resistant to network errors and capable of resume the
* download as soon as network conditions allow and in a completely
* transparent way for the user; note that in the global network error
* handling, there must be an automatic
* <pre>.retry()</pre>, as in the code example below.</p>
* <p>
* This method is useful if the server correctly returns Content-Length and
* if it supports partial downloads: if not, it works like a normal
* download.</p>
* <p>
* Pros: always allows you to complete downloads, even if very heavy (e.g.
* 100MB), even if the connection is unstable (network errors) and even if
* the app goes temporarily in the background (on some platforms the
* download will continue in the background, on others it will be
* temporarily suspended).</p>
* <p>
* Cons: since this method is based on splitting the download into small
* parts (512kbytes is the default), this approach causes many GET requests
* that slightly slow down the download and cause more traffic than normally
* needed.</p>
* <p>
* Usage example:</p>
* <script src="https://gist.github.com/jsfan3/554590a12c3102a3d77e17533e7eca98.js"></script>
*
* @param url
* @param fileName must be a valid Storage file name or FileSystemStorage
* file path
* @param percentageCallback invoked (in EDT) during the download to notify
* the progress (from 0 to 100); it can be null if you are not interested in
* monitoring the progress
* @param filesavedCallback invoked (in EDT) only when the download is
* finished; if null, no action is taken
* @throws IOException
*/
public static void downloadUrlSafely(String url, final String fileName, final OnComplete<Integer> percentageCallback, final OnComplete<String> filesavedCallback) throws IOException {
// Code discussion here: https://stackoverflow.com/a/62137379/1277576
String partialDownloadsDir = FileSystemStorage.getInstance().getAppHomePath() + FileSystemStorage.getInstance().getFileSystemSeparator() + "partialDownloads";
if (!FileSystemStorage.getInstance().isDirectory(partialDownloadsDir)) {
FileSystemStorage.getInstance().mkdir(partialDownloadsDir);
}
// do its best to be unique if there are parallel downloads
final String uniqueId = url.hashCode() + "" + downloadUrlSafelyRandom.nextInt();
final String partialDownloadPath = partialDownloadsDir + FileSystemStorage.getInstance().getFileSystemSeparator() + uniqueId;
// as discussed here: https://stackoverflow.com/a/57984257
final boolean isStorage = fileName.indexOf("/") < 0;
// total expected download size, with a check partial download support
final long fileSize = getFileSizeWithoutDownload(url, true);
// 512 kbyte, size of each small download
final int splittingSize = 512 * 1024;
final Wrapper<Long> downloadedTotalBytes = new Wrapper<Long>(0l);
final OutputStream out;
if (isStorage) {
// leave it open to append partial downloads
out = Storage.getInstance().createOutputStream(fileName);
} else {
out = FileSystemStorage.getInstance().openOutputStream(fileName);
}
// Codename One thread that supports crash protection and similar Codename One features.
final EasyThread mergeFilesThread = EasyThread.start("mergeFilesThread");
final ConnectionRequest cr = new GZConnectionRequest();
cr.setUrl(url);
cr.setPost(false);
if (fileSize > splittingSize) {
// Which byte should the download start from?
cr.addRequestHeader("Range", "bytes=0-" + splittingSize);
cr.setDestinationFile(partialDownloadPath);
} else {
Util.cleanup(out);
if (isStorage) {
cr.setDestinationStorage(fileName);
} else {
cr.setDestinationFile(fileName);
}
}
cr.addResponseListener(new ActionListener<NetworkEvent>() {
@Override
public void actionPerformed(NetworkEvent evt) {
mergeFilesThread.run(new Runnable() {
@Override
public void run() {
try {
// We append the just saved partial download to the fileName, if it exists
if (FileSystemStorage.getInstance().exists(partialDownloadPath)) {
InputStream in = FileSystemStorage.getInstance().openInputStream(partialDownloadPath);
Util.copyNoClose(in, out, 8192);
Util.cleanup(in);
// before deleting the file, we check and update how much data we have actually downloaded
downloadedTotalBytes.set(downloadedTotalBytes.get() + FileSystemStorage.getInstance().getLength(partialDownloadPath));
FileSystemStorage.getInstance().delete(partialDownloadPath);
}
// Is the download finished?
if (downloadedTotalBytes.get() > fileSize) {
throw new IllegalStateException("More content has been downloaded than the file length, check the code.");
}
if (fileSize <= 0 || downloadedTotalBytes.get() == fileSize) {
// yes, download finished
Util.cleanup(out);
if (filesavedCallback != null) {
CN.callSerially(new Runnable() {
@Override
public void run() {
filesavedCallback.completed(fileName);
}
});
}
} else {
// no, it's not finished, we repeat the request after updating the "Range" header
cr.addRequestHeader("Range", "bytes=" + downloadedTotalBytes.get() + "-" + (Math.min(downloadedTotalBytes.get() + splittingSize, fileSize)));
NetworkManager.getInstance().addToQueue(cr);
}
} catch (IOException ex) {
Log.p("Error in appending splitted file to output file", Log.ERROR);
Log.e(ex);
Log.sendLogAsync();
}
}
});
}
});
NetworkManager.getInstance().addToQueue(cr);
NetworkManager.getInstance().addProgressListener(new ActionListener<NetworkEvent>() {
@Override
public void actionPerformed(NetworkEvent evt) {
if (cr == evt.getConnectionRequest() && fileSize > 0) {
// the following casting to long is necessary when the file is bigger than 21MB, otherwise the result of the calculation is wrong
if (percentageCallback != null) {
CN.callSerially(new Runnable() {
@Override
public void run() {
percentageCallback.completed((int) ((long) downloadedTotalBytes.get() * 100 / fileSize));
}
});
}
}
}
});
}
Aggregations