public ByteBuffer run(Retriever retriever) { if (!retriever.getState().equals(Retriever.RETRIEVER_STATE_SUCCESSFUL)) return null; HTTPRetriever htr = (HTTPRetriever) retriever; if (htr.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT) { // Mark tile as missing to avoid excessive attempts MercatorTiledImageLayer.this.levels.markResourceAbsent(tile); return null; } if (htr.getResponseCode() != HttpURLConnection.HTTP_OK) return null; URLRetriever r = (URLRetriever) retriever; ByteBuffer buffer = r.getBuffer(); String suffix = WWIO.makeSuffixForMimeType(htr.getContentType()); if (suffix == null) { return null; // TODO: log error } String path = tile.getPath().substring(0, tile.getPath().lastIndexOf(".")); path += suffix; final File outFile = WorldWind.getDataFileStore().newFile(path); if (outFile == null) return null; try { WWIO.saveBuffer(buffer, outFile); return buffer; } catch (IOException e) { e.printStackTrace(); // TODO: log error return null; } }
/** * Resolves a reference to a local element identified by address and identifier, where {@code * linkBase} identifies a document, including the current document, and {@code linkRef} is the id * of the desired element. * * <p>If {@code linkBase} refers to a local COLLADA file and {@code linkRef} is non-null, the * return value is the element identified by {@code linkRef}. If {@code linkRef} is null, the * return value is a parsed {@link ColladaRoot} for the COLLADA file identified by {@code * linkBase}. Otherwise, {@code linkBase} is returned. * * @param linkBase the address of the document containing the requested element. * @param linkRef the element's identifier. * @return the requested element, or null if the element is not found. * @throws IllegalArgumentException if the address is null. */ protected Object resolveLocalReference(String linkBase, String linkRef) { if (linkBase == null) { String message = Logging.getMessage("nullValue.DocumentSourceIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } try { File file = new File(linkBase); if (!file.exists()) return null; // Determine whether the file is a COLLADA document. If not, just return the file path. if (!WWIO.isContentType(file, ColladaConstants.COLLADA_MIME_TYPE)) return file.toURI().toString(); // Attempt to open and parse the COLLADA file. ColladaRoot refRoot = ColladaRoot.createAndParse(file); // An exception is thrown if parsing fails, so no need to check for null. // Add the parsed file to the session cache so it doesn't have to be parsed again. WorldWind.getSessionCache().put(linkBase, refRoot); // Now check the newly opened COLLADA file for the referenced item, if a reference was // specified. if (linkRef != null) return refRoot.getItemByID(linkRef); else return refRoot; } catch (Exception e) { String message = Logging.getMessage("generic.UnableToResolveReference", linkBase + "/" + linkRef); Logging.logger().warning(message); return null; } }
/** * Resolves a reference to a remote element identified by address and identifier, where {@code * linkBase} identifies a remote document, and {@code linkRef} is the id of the desired element. * This method retrieves resources asynchronously using the {@link * gov.nasa.worldwind.cache.FileStore}. * * <p>The return value is null if the file is not yet available in the FileStore. If {@code * linkBase} refers to a COLLADA file and {@code linkRef} is non-null, the return value is the * element identified by {@code linkRef}. If {@code linkBase} refers to a COLLADA file and {@code * linkRef} is null, the return value is a parsed {@link ColladaRoot} for the COLLADA file * identified by {@code linkBase}. Otherwise the return value is a {@link URL} to the file in the * file cache. * * @param linkBase the address of the document containing the requested element. * @param linkRef the element's identifier. * @return URL to the requested file, parsed ColladaRoot, or COLLADA element. Returns null if the * document is not yet available in the FileStore. * @throws IllegalArgumentException if the {@code linkBase} is null. */ public Object resolveRemoteReference(String linkBase, String linkRef) { if (linkBase == null) { String message = Logging.getMessage("nullValue.DocumentSourceIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } try { // See if it's in the cache. If not, requestFile will start another thread to retrieve it and // return null. URL url = WorldWind.getDataFileStore().requestFile(linkBase); if (url == null) return null; // It's in the cache. If it's a COLLADA file try to parse it so we can search for the // specified reference. // If it's not COLLADA, just return the url for the cached file. String contentType = WorldWind.getDataFileStore().getContentType(linkBase); if (contentType == null) { String suffix = WWIO.getSuffix(linkBase.split(";")[0]); // strip of trailing garbage if (!WWUtil.isEmpty(suffix)) contentType = WWIO.makeMimeTypeForSuffix(suffix); } if (!this.canParseContentType(contentType)) return url; // If the file is a COLLADA document, attempt to open it. We can't open it as a File with // createAndParse // because the ColladaRoot that will be created needs to have the remote address in order to // resolve any // relative references within it. ColladaRoot refRoot = this.parseCachedColladaFile(url, linkBase); // Add the parsed file to the session cache so it doesn't have to be parsed again. WorldWind.getSessionCache().put(linkBase, refRoot); // Now check the newly opened COLLADA file for the referenced item, if a reference was // specified. if (linkRef != null) return refRoot.getItemByID(linkRef); else return refRoot; } catch (Exception e) { String message = Logging.getMessage("generic.UnableToResolveReference", linkBase + "/" + linkRef); Logging.logger().warning(message); return null; } }
public ComposeImageTile(Sector sector, String mimeType, Level level, int width, int height) throws IOException { super(sector, level, -1, -1); // row and column aren't used and need to signal that this.width = width; this.height = height; this.file = File.createTempFile(WWIO.DELETE_ON_EXIT_PREFIX, WWIO.makeSuffixForMimeType(mimeType)); }
/** * Create a new <code>ColladaRoot</code> for a {@link URL}. * * @param docSource the URL of the document. * @throws IllegalArgumentException if the document source is null. * @throws IOException if an error occurs while reading the Collada document. */ public ColladaRoot(URL docSource) throws IOException { super(ColladaConstants.COLLADA_NAMESPACE); if (docSource == null) { String message = Logging.getMessage("nullValue.DocumentSourceIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } URLConnection conn = docSource.openConnection(); this.colladaDoc = new ColladaInputStream(conn.getInputStream(), WWIO.makeURI(docSource)); this.initialize(); }
private BufferedImage requestImage(MercatorTextureTile tile, String mimeType) throws URISyntaxException { String pathBase = tile.getPath().substring(0, tile.getPath().lastIndexOf(".")); String suffix = WWIO.makeSuffixForMimeType(mimeType); String path = pathBase + suffix; URL url = WorldWind.getDataFileStore().findFile(path, false); if (url == null) // image is not local return null; if (WWIO.isFileOutOfDate(url, tile.getLevel().getExpiryTime())) { // The file has expired. Delete it. WorldWind.getDataFileStore().removeFile(url); String message = Logging.getMessage("generic.DataFileExpired", url); Logging.logger().fine(message); } else { try { File imageFile = new File(url.toURI()); BufferedImage image = ImageIO.read(imageFile); if (image == null) { String message = Logging.getMessage("generic.ImageReadFailed", imageFile); throw new RuntimeException(message); } this.levels.unmarkResourceAbsent(tile); return image; } catch (IOException e) { // Assume that something's wrong with the file and delete it. gov.nasa.worldwind.WorldWind.getDataFileStore().removeFile(url); this.levels.markResourceAbsent(tile); String message = Logging.getMessage("generic.DeletedCorruptDataFile", url); Logging.logger().info(message); } } return null; }
/** * Resolves a reference to a local or remote file or element. If the link refers to an element in * the current document, this method returns that element. If the link refers to a remote * document, this method will initiate asynchronous retrieval of the document, and return a URL of * the downloaded document in the file cache, if it is available locally. If the link identifies a * COLLADA document, the document will be returned as a parsed ColladaRoot. * * @param link the address of the document or element to resolve. This may be a full URL, a URL * fragment that identifies an element in the current document ("#myElement"), or a URL and a * fragment identifier ("http://server.com/model.dae#myElement"). * @return the requested element, or null if the element is not found. * @throws IllegalArgumentException if the address is null. */ public Object resolveReference(String link) { if (link == null) { String message = Logging.getMessage("nullValue.DocumentSourceIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } try { String[] linkParts = link.split("#"); String linkBase = linkParts[0]; String linkRef = linkParts.length > 1 ? linkParts[1] : null; // See if it's a reference to an internal element. if (WWUtil.isEmpty(linkBase) && !WWUtil.isEmpty(linkRef)) return this.getItemByID(linkRef); // Interpret the path relative to the current document. String path = this.getSupportFilePath(linkBase); if (path == null) path = linkBase; // See if it's an already found and parsed COLLADA file. Object o = WorldWind.getSessionCache().get(path); if (o != null && o instanceof ColladaRoot) return linkRef != null ? ((ColladaRoot) o).getItemByID(linkRef) : o; URL url = WWIO.makeURL(path); if (url == null) { // See if the reference can be resolved to a local file. o = this.resolveLocalReference(path, linkRef); } // If we didn't find a local file, treat it as a remote reference. if (o == null) o = this.resolveRemoteReference(path, linkRef); if (o != null) return o; // If the reference was not resolved as a remote reference, look for a local element // identified by the // reference string. This handles the case of malformed internal references that omit the # // sign at the // beginning of the reference. return this.getItemByID(link); } catch (Exception e) { String message = Logging.getMessage("generic.UnableToResolveReference", link); Logging.logger().warning(message); } return null; }
/** * Open and parse the specified file expressed as a file: URL.. * * @param url the URL of the file to open, expressed as a URL with a scheme of "file". * @param linkBase the original address of the document if the file is a retrieved and cached * file. * @return A {@code ColladaRoot} representing the file's COLLADA contents. * @throws IOException if an I/O error occurs during opening and parsing. * @throws XMLStreamException if a server parsing error is encountered. */ protected ColladaRoot parseCachedColladaFile(URL url, String linkBase) throws IOException, XMLStreamException { ColladaDoc colladaDoc; InputStream refStream = url.openStream(); colladaDoc = new ColladaInputStream(refStream, WWIO.makeURI(linkBase)); try { ColladaRoot refRoot = new ColladaRoot(colladaDoc); refRoot.parse(); // also closes the URL's stream return refRoot; } catch (XMLStreamException e) { refStream.close(); // parsing failed, so explicitly close the stream throw e; } }
/** * Determine if a host is reachable by attempting to resolve the host name, and then attempting to * open a connection. * * @param hostName Name of the host to connect to. * @return {@code true} if a the host is reachable, {@code false} if the host name cannot be * resolved, or if opening a connection to the host fails. */ protected static boolean isHostReachable(String hostName) { try { // Assume host is unreachable if we can't get its dns entry without getting an exception //noinspection ResultOfMethodCallIgnored InetAddress.getByName(hostName); } catch (UnknownHostException e) { String message = Logging.getMessage("NetworkStatus.UnreachableTestHost", hostName); Logging.verbose(message); return false; } catch (Exception e) { String message = Logging.getMessage("NetworkStatus.ExceptionTestingHost", hostName); Logging.verbose(message); return false; } // Was able to get internet address, but host still might not be reachable because the address // might have been // cached earlier when it was available. So need to try something else. URLConnection connection = null; try { URL url = new URL("http://" + hostName); Proxy proxy = WWIO.configureProxy(); if (proxy != null) connection = url.openConnection(proxy); else connection = url.openConnection(); connection.setConnectTimeout(2000); connection.setReadTimeout(2000); String ct = connection.getContentType(); if (ct != null) return true; } catch (IOException e) { String message = Logging.getMessage("NetworkStatus.ExceptionTestingHost", hostName); Logging.info(message); } finally { if (connection instanceof HttpURLConnection) ((HttpURLConnection) connection).disconnect(); } return false; }
/** * Creates a Collada root for an untyped source. The source must be either a {@link File} or a * {@link String} identifying either a file path or a {@link URL}. Null is returned if the source * type is not recognized. * * @param docSource either a {@link File} or a {@link String} identifying a file path or {@link * URL}. * @return a new {@link ColladaRoot} for the specified source, or null if the source type is not * supported. * @throws IllegalArgumentException if the source is null. * @throws IOException if an error occurs while reading the source. */ public static ColladaRoot create(Object docSource) throws IOException { if (docSource == null) { String message = Logging.getMessage("nullValue.DocumentSourceIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (docSource instanceof File) { return new ColladaRoot((File) docSource); } else if (docSource instanceof URL) { return new ColladaRoot((URL) docSource); } else if (docSource instanceof String) { File file = new File((String) docSource); if (file.exists()) return new ColladaRoot(file); URL url = WWIO.makeURL(docSource); if (url != null) return new ColladaRoot(url); } else if (docSource instanceof InputStream) { return new ColladaRoot((InputStream) docSource); } return null; }