001package ch.gbrain.gwtstorage.manager;
002
003/*
004 * #%L
005 * GwtStorage
006 * %%
007 * Copyright (C) 2016 gbrain.ch
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023
024import java.util.logging.Level;
025import java.util.logging.Logger;
026
027import ch.gbrain.gwtstorage.model.StorageResource;
028
029import com.google.gwt.core.client.Callback;
030import com.google.gwt.user.client.Command;
031import com.googlecode.gwtphonegap.client.PhoneGap;
032import com.googlecode.gwtphonegap.client.file.DirectoryEntry;
033import com.googlecode.gwtphonegap.client.file.FileCallback;
034import com.googlecode.gwtphonegap.client.file.FileDownloadCallback;
035import com.googlecode.gwtphonegap.client.file.FileEntry;
036import com.googlecode.gwtphonegap.client.file.FileTransfer;
037import com.googlecode.gwtphonegap.client.file.FileTransferError;
038import com.googlecode.gwtphonegap.client.file.FileTransferProgressEvent;
039
040public class StorageResourceCollector implements Command
041{
042  private Logger logger;
043  private StorageManager storageManager;
044  private PhoneGap phonegap;
045  private StorageResource storageResource;
046  
047  public StorageResourceCollector(StorageManager storageManager, StorageResource storageResource)
048  {
049    this.storageManager = storageManager;
050    this.logger = storageManager.getLogger();
051    this.phonegap = storageManager.getPhonegap();
052    this.storageResource = storageResource;
053  }
054  
055  @Override
056  public void execute()
057  {
058    try
059    {
060      Boolean versionCheck = storageManager.checkResourceVersion(storageResource);
061      if (versionCheck == null)
062      {
063        logger.log(Level.WARNING, "ResourceCacheReference retrieval no chache entry found : " + storageResource.getResourceUrl()+ " requestedVersion:" + storageResource.getVersion() + " -> invoke loading");
064        downloadCacheResource(storageResource);
065      } else if (versionCheck == true)
066      {
067        // it should be there already and version is ok
068        logger.log(Level.INFO, "Successful ResourceCacheReference retrieval : " + storageResource.getResourceUrl());
069        // check if it really exists but asynch
070        String fileName = storageManager.convertFilePathToFileName(storageResource.getResourceUrl());
071        storageManager.getLocalFileReference(storageManager.getCacheDirectory(), fileName, false, new FileCallback<FileEntry, StorageError>()
072        {
073          @Override
074          public void onSuccess(FileEntry entry)
075          {
076            logger.log(Level.INFO, "Successful ResourceCacheFile retrieval : " + storageResource.getResourceUrl());
077            // the cache is ok, file is there in right version, we don't have to
078            // do something really.
079            if (storageResource.getDownloadNotification()!=null)
080            {
081              storageResource.getDownloadNotification().onSuccess(entry);
082            }
083          }
084          @Override
085          public void onFailure(StorageError error)
086          {
087            logger.log(Level.SEVERE, "Failure ResourceCacheReference retrieval : " + storageResource.getResourceUrl() + " : " + error.toString());
088            // nothing found, we must try to download again
089            downloadCacheResource(storageResource);
090          }
091        });
092      } else if (versionCheck == false)
093      {
094        // version doesn't match, invoke reload
095        logger.log(Level.WARNING, "ResourceCacheReference retrieval version mismatch : " + storageResource.getResourceUrl() + " requestedVersion:" + storageResource.getVersion() + " -> invoke loading");
096        downloadCacheResource(storageResource);
097      }
098    } catch (Exception ex)
099    {
100      logger.log(Level.SEVERE, "Exception checking ResourceCache", ex);
101    }
102    
103  }
104
105  
106  /**
107   * Download the given resource url and store it in the local cache Directory.
108   * 
109   * @param resource
110   * @param destinationDir The URL of the destination Directoy
111   */
112  public void downloadCacheResource(final StorageResource resource)
113  {
114    try
115    {
116      if (resource == null) return;
117      logger.log(Level.INFO, "downloadCacheResource " + resource.getResourceUrl() + " Version:" + resource.getVersion());
118      storageManager.getCacheDirectoryEntry(new Callback<DirectoryEntry, StorageError>()
119      {
120        public void onSuccess(DirectoryEntry cacheDir)
121        {
122          try
123          {
124            FileTransfer fileTransfer = phonegap.getFile().createFileTransfer();
125            String localFileName = storageManager.convertFilePathToFileName(resource.getResourceUrl());
126            String sourceUrl = storageManager.getRemoteAppBaseUrl() + resource.getResourceUrl();
127            String destUrl = cacheDir.toURL() + localFileName;
128            // String destUrl =
129            // "cdvfile://localhost/persistent/testapp/test.mp4";
130            logger.log(Level.INFO, "downloadResource invoked for : " + sourceUrl + " to : " + destUrl);
131            fileTransfer.download(sourceUrl, destUrl, getResourceDownloadHandler(resource));
132          } catch (Exception lex)
133          {
134            logger.log(Level.SEVERE, "Exception in downloadCacheResource success handler", lex);
135          }
136        }
137
138        public void onFailure(StorageError error)
139        {
140          logger.log(Level.WARNING, "Failed to download CacheResource for : " + resource.getResourceUrl());
141          if (resource.getDownloadNotification()!=null)
142          {
143            resource.getDownloadNotification().onFailure(new TransferError(error.getErrorCode(),error.getErrorReason()));
144          }
145        }
146      });
147    } catch (Exception ex)
148    {
149      logger.log(Level.SEVERE, "Exception resourceDownload for : " + resource.getResourceUrl(), ex);
150    }
151  }
152
153  /**
154   * Creates and returns a Callback which treats the result for a url resource
155   * retrieval The just downloaded resource is registered in the local storage
156   * with the version for future cache handling
157   * 
158   * @return The callback which deals with the asynch result of the remote
159   *         resource retrieval
160   */
161  private FileDownloadCallback getResourceDownloadHandler(final StorageResource resource)
162  {
163    return new FileDownloadCallback()
164    {
165      public void onSuccess(FileEntry fileEntry)
166      {
167        try
168        {
169          logger.log(Level.INFO, "FileDownload success " + fileEntry.getFullPath() + " for resource=" + resource.getResourceUrl() + " version=" + resource.getVersion());
170          // register now in the storage the version for the cache checks in the
171          // future
172          storageManager.getLocalStorage().setItem(resource.getResourceIdKey(), fileEntry.toURL());
173          storageManager.getLocalStorage().setItem(resource.getResourceVersionKey(), resource.getVersion().toString());
174          //cacheCheckInProgress = false;
175          if (resource.getDownloadNotification()!=null)
176          {
177            resource.getDownloadNotification().onSuccess(fileEntry);
178          }
179        } catch (Exception lex)
180        {
181          logger.log(Level.SEVERE, "Exception on cacheResource download success handler", lex);
182        }
183      }
184
185      public void onProgress(FileTransferProgressEvent progress)
186      {
187        if (resource.getDownloadNotification()!=null)
188        {
189          resource.getDownloadNotification().onProgress(progress);
190        }        
191      }
192
193      public void onFailure(FileTransferError error)
194      {
195        logger.log(Level.SEVERE, "FileDownload Failure " + error.toString() + " : " + resource.getResourceUrl());
196        //cacheCheckInProgress = false;
197        if (resource.getDownloadNotification()!=null)
198        {
199          resource.getDownloadNotification().onFailure(error);
200        }
201      }
202    };
203  }
204  
205  
206  
207}