List of usage examples for java.net URI getFragment
public String getFragment()
From source file:it.infn.ct.futuregateway.apiserver.inframanager.SessionBuilder.java
/** * Read the proxy certificate from a remote location. * The location is retrieved from the parameters. * * @return A string representation of the proxy * @throws InfrastructureException If the proxy for the infrastructure * cannot be retrieved for problems with the parameters *///from www . j ava2 s .co m protected final String readRemoteProxy() throws InfrastructureException { URL proxy; if (params.getProperty("proxyurl") == null && params.getProperty("etokenserverurl") == null) { throw new InfrastructureException( "No proxy location in " + "configuration parameters for " + infrastructure.getId()); } if (params.getProperty("proxyurl") != null) { try { proxy = new URL(params.getProperty("proxyurl")); } catch (MalformedURLException mue) { throw new InfrastructureException("URL for the proxy is not " + "valid, infrastructure " + infrastructure.getId() + " is not accessible"); } } else { try { URI etokenurl = new URI(params.getProperty("etokenserverurl")); StringBuilder queryURI = new StringBuilder(); StringBuilder pathURI = new StringBuilder(); String oldPath = etokenurl.getPath(); if (oldPath != null) { pathURI.append(oldPath); if (!oldPath.endsWith("/")) { pathURI.append('/'); } pathURI.append(params.getProperty("etokenid", "")); } else { pathURI.append('/').append(params.getProperty("etokenid", "")); } String oldQuery = etokenurl.getQuery(); if (oldQuery != null) { queryURI.append(oldQuery).append('&'); } queryURI.append("voms=").append(params.getProperty("vo", "")).append(':') .append(params.getProperty("voroles", "")).append('&'); queryURI.append("proxy-renewal=").append(params.getProperty("proxyrenewal", Defaults.PROXYRENEWAL)) .append('&'); queryURI.append("disable-voms-proxy=") .append(params.getProperty("disablevomsproxy", Defaults.DISABLEVOMSPROXY)).append('&'); queryURI.append("rfc-proxy=").append(params.getProperty("rfcproxy", Defaults.RFCPROXY)).append('&'); queryURI.append("cn-label="); if (user != null) { queryURI.append("eToken:").append(user); } etokenurl = new URI(etokenurl.getScheme(), etokenurl.getUserInfo(), etokenurl.getHost(), etokenurl.getPort(), pathURI.toString(), queryURI.toString(), etokenurl.getFragment()); proxy = etokenurl.toURL(); } catch (MalformedURLException | URISyntaxException use) { throw new InfrastructureException("etokenserverurl not " + "properly configured for infrastructure " + getInfrastructure().getId()); } } StringBuilder strProxy = new StringBuilder(); log.debug("Accessing the proxy " + proxy.toString()); try { String lnProxy; BufferedReader fileProxy = new BufferedReader(new InputStreamReader(proxy.openStream())); while ((lnProxy = fileProxy.readLine()) != null) { strProxy.append(lnProxy); strProxy.append("\n"); } } catch (IOException ioer) { log.error("Impossible to retrieve the remote proxy certificate from" + ": " + proxy.toString()); } log.debug("Proxy:\n\n" + strProxy.toString() + "\n\n"); return strProxy.toString(); }
From source file:org.apache.nifi.web.api.VersionsResource.java
@POST @Consumes(MediaType.APPLICATION_JSON)/*from w ww . j a v a 2 s .c o m*/ @Produces(MediaType.APPLICATION_JSON) @Path("process-groups/{id}") @ApiOperation(value = "Save the Process Group with the given ID", response = VersionControlInformationEntity.class, notes = "Begins version controlling the Process Group with the given ID or commits changes to the Versioned Flow, " + "depending on if the provided VersionControlInformation includes a flowId. " + NON_GUARANTEED_ENDPOINT, authorizations = { @Authorization(value = "Read - /process-groups/{uuid}"), @Authorization(value = "Write - /process-groups/{uuid}"), @Authorization(value = "Read - /{component-type}/{uuid} - For all encapsulated components"), @Authorization(value = "Read - any referenced Controller Services by any encapsulated components - /controller-services/{uuid}") }) @ApiResponses(value = { @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 404, message = "The specified resource could not be found."), @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") }) public Response saveToFlowRegistry(@ApiParam("The process group id.") @PathParam("id") final String groupId, @ApiParam(value = "The versioned flow details.", required = true) final StartVersionControlRequestEntity requestEntity) { // Verify the request final RevisionDTO revisionDto = requestEntity.getProcessGroupRevision(); if (revisionDto == null) { throw new IllegalArgumentException("Process Group Revision must be specified"); } final VersionedFlowDTO versionedFlowDto = requestEntity.getVersionedFlow(); if (versionedFlowDto == null) { throw new IllegalArgumentException("Version Control Information must be supplied."); } if (StringUtils.isEmpty(versionedFlowDto.getBucketId())) { throw new IllegalArgumentException("The Bucket ID must be supplied."); } if (StringUtils.isEmpty(versionedFlowDto.getFlowName()) && StringUtils.isEmpty(versionedFlowDto.getFlowId())) { throw new IllegalArgumentException("The Flow Name or Flow ID must be supplied."); } if (versionedFlowDto.getFlowName() != null && versionedFlowDto.getFlowName().length() > 1000) { throw new IllegalArgumentException("The Flow Name cannot exceed 1,000 characters"); } if (StringUtils.isEmpty(versionedFlowDto.getRegistryId())) { throw new IllegalArgumentException("The Registry ID must be supplied."); } if (versionedFlowDto.getDescription() != null && versionedFlowDto.getDescription().length() > 65535) { throw new IllegalArgumentException("Flow Description cannot exceed 65,535 characters"); } if (versionedFlowDto.getComments() != null && versionedFlowDto.getComments().length() > 65535) { throw new IllegalArgumentException("Comments cannot exceed 65,535 characters"); } if (isDisconnectedFromCluster()) { verifyDisconnectedNodeModification(requestEntity.isDisconnectedNodeAcknowledged()); } // ensure we're not attempting to version the root group final ProcessGroupEntity root = serviceFacade.getProcessGroup(FlowManager.ROOT_GROUP_ID_ALIAS); if (root.getId().equals(groupId)) { throw new IllegalArgumentException("The Root Process Group cannot be versioned."); } if (isReplicateRequest()) { // We first have to obtain a "lock" on all nodes in the cluster so that multiple Version Control requests // are not being made simultaneously. We do this by making a POST to /nifi-api/versions/active-requests. // The Response gives us back the Request ID. final URI requestUri; try { final URI originalUri = getAbsolutePath(); final String requestId = lockVersionControl(originalUri, groupId); requestUri = new URI(originalUri.getScheme(), originalUri.getUserInfo(), originalUri.getHost(), originalUri.getPort(), "/nifi-api/versions/active-requests/" + requestId, null, originalUri.getFragment()); } catch (final URISyntaxException e) { throw new RuntimeException(e); } // Now that we have the Request, we know that no other thread is updating the Flow Registry. So we can now // create the Flow in the Flow Registry and push the Process Group as the first version of the Flow. Once we've // succeeded with that, we need to update all nodes' Process Group to contain the new Version Control Information. // Finally, we can delete the Request. try { final VersionControlComponentMappingEntity mappingEntity = serviceFacade .registerFlowWithFlowRegistry(groupId, requestEntity); replicateVersionControlMapping(mappingEntity, requestEntity, requestUri, groupId); final VersionControlInformationEntity responseEntity = serviceFacade .getVersionControlInformation(groupId); return generateOkResponse(responseEntity).build(); } finally { unlockVersionControl(requestUri, groupId); } } // Perform local task. If running in a cluster environment, we will never get to this point. This is because // in the above block, we check if (isReplicate()) and if true, we implement the 'cluster logic', but this // does not involve replicating the actual request, because we only want a single node to handle the logic of // creating the flow in the Registry. final Revision groupRevision = new Revision(revisionDto.getVersion(), revisionDto.getClientId(), groupId); return withWriteLock(serviceFacade, requestEntity, groupRevision, lookup -> { final ProcessGroupAuthorizable groupAuthorizable = lookup.getProcessGroup(groupId); final Authorizable processGroup = groupAuthorizable.getAuthorizable(); // require write to this group processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser()); // require read to this group and all descendants authorizeProcessGroup(groupAuthorizable, authorizer, lookup, RequestAction.READ, true, false, true, true); }, () -> { final VersionedFlowDTO versionedFlow = requestEntity.getVersionedFlow(); final String registryId = versionedFlow.getRegistryId(); final String bucketId = versionedFlow.getBucketId(); final String flowId = versionedFlow.getFlowId(); serviceFacade.verifyCanSaveToFlowRegistry(groupId, registryId, bucketId, flowId); }, (rev, flowEntity) -> { // Register the current flow with the Flow Registry. final VersionControlComponentMappingEntity mappingEntity = serviceFacade .registerFlowWithFlowRegistry(groupId, flowEntity); // Update the Process Group's Version Control Information final VersionControlInformationEntity responseEntity = serviceFacade.setVersionControlInformation(rev, groupId, mappingEntity.getVersionControlInformation(), mappingEntity.getVersionControlComponentMapping()); return generateOkResponse(responseEntity).build(); }); }
From source file:org.apache.nifi.registry.web.api.ApplicationResource.java
protected URI getBaseUri() { final UriBuilder uriBuilder = uriInfo.getBaseUriBuilder(); URI uri = uriBuilder.build(); try {/*from w ww . j a va 2s. c o m*/ // check for proxy settings final String scheme = getFirstHeaderValue(PROXY_SCHEME_HTTP_HEADER, FORWARDED_PROTO_HTTP_HEADER); final String host = getFirstHeaderValue(PROXY_HOST_HTTP_HEADER, FORWARDED_HOST_HTTP_HEADER); final String port = getFirstHeaderValue(PROXY_PORT_HTTP_HEADER, FORWARDED_PORT_HTTP_HEADER); String baseContextPath = getFirstHeaderValue(PROXY_CONTEXT_PATH_HTTP_HEADER, FORWARDED_CONTEXT_HTTP_HEADER); // if necessary, prepend the context path String resourcePath = uri.getPath(); if (baseContextPath != null) { // normalize context path if (!baseContextPath.startsWith("/")) { baseContextPath = "/" + baseContextPath; } if (baseContextPath.endsWith("/")) { baseContextPath = StringUtils.substringBeforeLast(baseContextPath, "/"); } // determine the complete resource path resourcePath = baseContextPath + resourcePath; } // determine the port uri int uriPort = uri.getPort(); if (port != null) { if (StringUtils.isWhitespace(port)) { uriPort = -1; } else { try { uriPort = Integer.parseInt(port); } catch (final NumberFormatException nfe) { logger.warn(String.format( "Unable to parse proxy port HTTP header '%s'. Using port from request URI '%s'.", port, uriPort)); } } } // construct the URI uri = new URI((StringUtils.isBlank(scheme)) ? uri.getScheme() : scheme, uri.getUserInfo(), (StringUtils.isBlank(host)) ? uri.getHost() : host, uriPort, resourcePath, uri.getQuery(), uri.getFragment()); } catch (final URISyntaxException use) { throw new UriBuilderException(use); } return uri; }
From source file:com.microsoft.azure.storage.core.Utility.java
/** * Determines the relative difference between the two specified URIs. * /*from w ww . ja v a 2s.com*/ * @param baseURI * A <code>java.net.URI</code> object that represents the base URI for which <code>toUri</code> will be * made relative. * @param toUri * A <code>java.net.URI</code> object that represents the URI to make relative to <code>baseURI</code>. * * @return A <code>String</code> that either represents the relative URI of <code>toUri</code> to * <code>baseURI</code>, or the URI of <code>toUri</code> itself, depending on whether the hostname and * scheme are identical for <code>toUri</code> and <code>baseURI</code>. If the hostname and scheme of * <code>baseURI</code> and <code>toUri</code> are identical, this method returns an unencoded relative URI * such that if appended to <code>baseURI</code>, it will yield <code>toUri</code>. If the hostname or * scheme of <code>baseURI</code> and <code>toUri</code> are not identical, this method returns an unencoded * full URI specified by <code>toUri</code>. * * @throws URISyntaxException * If <code>baseURI</code> or <code>toUri</code> is invalid. */ public static String safeRelativize(final URI baseURI, final URI toUri) throws URISyntaxException { // For compatibility followed // http://msdn.microsoft.com/en-us/library/system.uri.makerelativeuri.aspx // if host and scheme are not identical return from uri if (!baseURI.getHost().equals(toUri.getHost()) || !baseURI.getScheme().equals(toUri.getScheme())) { return toUri.toString(); } final String basePath = baseURI.getPath(); String toPath = toUri.getPath(); int truncatePtr = 1; // Seek to first Difference // int maxLength = Math.min(basePath.length(), toPath.length()); int m = 0; int ellipsesCount = 0; for (; m < basePath.length(); m++) { if (m >= toPath.length()) { if (basePath.charAt(m) == '/') { ellipsesCount++; } } else { if (basePath.charAt(m) != toPath.charAt(m)) { break; } else if (basePath.charAt(m) == '/') { truncatePtr = m + 1; } } } // ../containername and ../containername/{path} should increment the truncatePtr // otherwise toPath will incorrectly begin with /containername if (m < toPath.length() && toPath.charAt(m) == '/') { // this is to handle the empty directory case with the '/' delimiter // for example, ../containername/ and ../containername// should not increment the truncatePtr if (!(toPath.charAt(m - 1) == '/' && basePath.charAt(m - 1) == '/')) { truncatePtr = m + 1; } } if (m == toPath.length()) { // No path difference, return query + fragment return new URI(null, null, null, toUri.getQuery(), toUri.getFragment()).toString(); } else { toPath = toPath.substring(truncatePtr); final StringBuilder sb = new StringBuilder(); while (ellipsesCount > 0) { sb.append("../"); ellipsesCount--; } if (!Utility.isNullOrEmpty(toPath)) { sb.append(toPath); } if (!Utility.isNullOrEmpty(toUri.getQuery())) { sb.append("?"); sb.append(toUri.getQuery()); } if (!Utility.isNullOrEmpty(toUri.getFragment())) { sb.append("#"); sb.append(toUri.getRawFragment()); } return sb.toString(); } }
From source file:org.apache.hadoop.fs.HarFileSystem.java
/** * decode the raw URI to get the underlying URI * @param rawURI raw Har URI/*from w ww . jav a 2s.co m*/ * @return filtered URI of the underlying fileSystem */ private URI decodeHarURI(URI rawURI, Configuration conf) throws IOException { String tmpAuth = rawURI.getAuthority(); //we are using the default file //system in the config //so create a underlying uri and //return it if (tmpAuth == null) { //create a path return FileSystem.getDefaultUri(conf); } String authority = rawURI.getAuthority(); int i = authority.indexOf('-'); if (i < 0) { throw new IOException("URI: " + rawURI + " is an invalid Har URI since '-' not found." + " Expecting har://<scheme>-<host>/<path>."); } if (rawURI.getQuery() != null) { // query component not allowed throw new IOException("query component in Path not supported " + rawURI); } URI tmp; try { // convert <scheme>-<host> to <scheme>://<host> URI baseUri = new URI(authority.replaceFirst("-", "://")); tmp = new URI(baseUri.getScheme(), baseUri.getAuthority(), rawURI.getPath(), rawURI.getQuery(), rawURI.getFragment()); } catch (URISyntaxException e) { throw new IOException( "URI: " + rawURI + " is an invalid Har URI. Expecting har://<scheme>-<host>/<path>."); } return tmp; }
From source file:org.apache.hadoop.mapred.JobClient.java
private void copyAndConfigureFiles(JobConf job, Path submitJobDir, short replication) throws IOException, InterruptedException { if (!(job.getBoolean("mapred.used.genericoptionsparser", false))) { LOG.warn("Use GenericOptionsParser for parsing the arguments. " + "Applications should implement Tool for the same."); }/*from ww w .j a v a 2 s .c o m*/ // Retrieve command line arguments placed into the JobConf // by GenericOptionsParser. String files = job.get("tmpfiles"); String libjars = job.get("tmpjars"); String archives = job.get("tmparchives"); // // Figure out what fs the JobTracker is using. Copy the // job to it, under a temporary name. This allows DFS to work, // and under the local fs also provides UNIX-like object loading // semantics. (that is, if the job file is deleted right after // submission, we can still run the submission to completion) // // Create a number of filenames in the JobTracker's fs namespace FileSystem fs = submitJobDir.getFileSystem(job); LOG.debug("default FileSystem: " + fs.getUri()); if (fs.exists(submitJobDir)) { throw new IOException("Not submitting job. Job directory " + submitJobDir + " already exists!! This is unexpected.Please check what's there in" + " that directory"); } submitJobDir = fs.makeQualified(submitJobDir); FsPermission mapredSysPerms = new FsPermission(JobSubmissionFiles.JOB_DIR_PERMISSION); FileSystem.mkdirs(fs, submitJobDir, mapredSysPerms); Path filesDir = JobSubmissionFiles.getJobDistCacheFiles(submitJobDir); Path archivesDir = JobSubmissionFiles.getJobDistCacheArchives(submitJobDir); Path libjarsDir = JobSubmissionFiles.getJobDistCacheLibjars(submitJobDir); // add all the command line files/ jars and archive // first copy them to jobtrackers filesystem if (files != null) { FileSystem.mkdirs(fs, filesDir, mapredSysPerms); String[] fileArr = files.split(","); for (String tmpFile : fileArr) { URI tmpURI; try { tmpURI = new URI(tmpFile); } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } Path tmp = new Path(tmpURI); Path newPath = copyRemoteFiles(fs, filesDir, tmp, job, replication); try { URI pathURI = getPathURI(newPath, tmpURI.getFragment()); DistributedCache.addCacheFile(pathURI, job); } catch (URISyntaxException ue) { //should not throw a uri exception throw new IOException("Failed to create uri for " + tmpFile, ue); } DistributedCache.createSymlink(job); } } if (libjars != null) { FileSystem.mkdirs(fs, libjarsDir, mapredSysPerms); String[] libjarsArr = libjars.split(","); for (String tmpjars : libjarsArr) { Path tmp = new Path(tmpjars); Path newPath = copyRemoteFiles(fs, libjarsDir, tmp, job, replication); DistributedCache.addArchiveToClassPath(new Path(newPath.toUri().getPath()), job, fs); } } if (archives != null) { FileSystem.mkdirs(fs, archivesDir, mapredSysPerms); String[] archivesArr = archives.split(","); for (String tmpArchives : archivesArr) { URI tmpURI; try { tmpURI = new URI(tmpArchives); } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } Path tmp = new Path(tmpURI); Path newPath = copyRemoteFiles(fs, archivesDir, tmp, job, replication); try { URI pathURI = getPathURI(newPath, tmpURI.getFragment()); DistributedCache.addCacheArchive(pathURI, job); } catch (URISyntaxException ue) { //should not throw an uri excpetion throw new IOException("Failed to create uri for " + tmpArchives, ue); } DistributedCache.createSymlink(job); } } // First we check whether the cached archives and files are legal. TrackerDistributedCacheManager.validate(job); // set the timestamps of the archives and files TrackerDistributedCacheManager.determineTimestamps(job); // set the public/private visibility of the archives and files TrackerDistributedCacheManager.determineCacheVisibilities(job); // get DelegationTokens for cache files TrackerDistributedCacheManager.getDelegationTokens(job, job.getCredentials()); String originalJarPath = job.getJar(); if (originalJarPath != null) { // copy jar to JobTracker's fs // use jar name if job is not named. if ("".equals(job.getJobName())) { job.setJobName(new Path(originalJarPath).getName()); } Path submitJarFile = JobSubmissionFiles.getJobJar(submitJobDir); job.setJar(submitJarFile.toString()); fs.copyFromLocalFile(new Path(originalJarPath), submitJarFile); fs.setReplication(submitJarFile, replication); fs.setPermission(submitJarFile, new FsPermission(JobSubmissionFiles.JOB_FILE_PERMISSION)); } else { LOG.warn("No job jar file set. User classes may not be found. " + "See JobConf(Class) or JobConf#setJar(String)."); } }
From source file:com.cloud.hypervisor.vmware.mo.HypervisorHostHelper.java
public static String resolveHostNameInUrl(DatacenterMO dcMo, String url) { s_logger.info("Resolving host name in url through vCenter, url: " + url); URI uri; try {/* ww w. ja v a 2 s . co m*/ uri = new URI(url); } catch (URISyntaxException e) { s_logger.warn("URISyntaxException on url " + url); return url; } String host = uri.getHost(); if (NetUtils.isValidIp(host)) { s_logger.info("host name in url is already in IP address, url: " + url); return url; } try { ManagedObjectReference morHost = dcMo.findHost(host); if (morHost != null) { HostMO hostMo = new HostMO(dcMo.getContext(), morHost); String managementPortGroupName; if (hostMo.getHostType() == VmwareHostType.ESXi) managementPortGroupName = (String) dcMo.getContext().getStockObject("manageportgroup"); else managementPortGroupName = (String) dcMo.getContext().getStockObject("serviceconsole"); VmwareHypervisorHostNetworkSummary summary = hostMo .getHyperHostNetworkSummary(managementPortGroupName); if (summary == null) { s_logger.warn("Unable to resolve host name in url through vSphere, url: " + url); return url; } String hostIp = summary.getHostIp(); try { URI resolvedUri = new URI(uri.getScheme(), uri.getUserInfo(), hostIp, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment()); s_logger.info("url " + url + " is resolved to " + resolvedUri.toString() + " through vCenter"); return resolvedUri.toString(); } catch (URISyntaxException e) { assert (false); return url; } } } catch (Exception e) { s_logger.warn("Unexpected exception ", e); } return url; }
From source file:net.sf.taverna.t2.security.credentialmanager.impl.CredentialManagerImpl.java
/** * Normalize an URI for insertion as the basis for path-recursive lookups, * ie. strip query and filename. For example: * //from w w w . ja v a2 s. c o m * <pre> * URI uri = URI.create("http://foo.org/dir1/dirX/../dir2/filename.html?q=x") * System.out.println(CredentialManager.normalizeServiceURI(uri)); * >>> http://foo.org/dir1/dir2/ * uri = URI.create("http://foo.org/dir1/dir2/"); * System.out.println(CredentialManager.normalizeServiceURI(uri)); * >>> http://foo.org/dir1/dir2/ * </pre> * <p> * Note that #fragments are preserved, as these are used to indicate HTTP * Basic Auth realms * * @param serviceURI * URI for a service that is to be normalized * @return A normalized URI without query, userinfo or filename, ie. where * uri.resolve(".").equals(uri). */ public URI normalizeServiceURI(URI serviceURI) { try { // Strip userinfo, keep fragment URI normalized = dnParser.setUserInfoForURI(serviceURI, null).normalize(); return dnParser.setFragmentForURI(normalized.resolve("."), serviceURI.getFragment()); } catch (URISyntaxException ex) { return serviceURI; } }
From source file:net.sf.taverna.t2.security.credentialmanager.impl.CredentialManagerImpl.java
protected Map<URI, URI> getFragmentMappedURIsForAllUsernameAndPasswordPairs() throws CMException { synchronized (Security.class) {// FIXME synchonization on strange thing! if (cachedServiceURIsMap == null) { HashMap<URI, URI> map = new HashMap<>(); // Get all service URIs that have username and password in the // Keystore for (URI serviceURI : getServiceURIsForAllUsernameAndPasswordPairs()) { // Always store 1-1, with or without fragment map.put(serviceURI, serviceURI); if (serviceURI.getFragment() == null) continue; // Look up the no-fragment uri as an additional mapping URI noFragment;/*w w w . j av a 2 s . c o m*/ try { noFragment = dnParser.setFragmentForURI(serviceURI, null); } catch (URISyntaxException e) { logger.warn("Could not reset fragment for service URI " + serviceURI); continue; } if (map.containsKey(noFragment)) { if (map.get(noFragment).getFragment() != null) { // No mapping for duplicates map.remove(noFragment); continue; } // else it's noFragment -> noFragment, which is OK } else { // Brand new, put it in map.put(noFragment, serviceURI); } } cachedServiceURIsMap = map; } return cachedServiceURIsMap; } }
From source file:net.www_eee.portal.channels.ProxyChannel.java
/** * <p>/*ww w . j a v a 2s . co m*/ * Rewrite a <code>linkURI</code> associated with a <code>proxiedFileURL</code>, if required. * </p> * * <p> * Technically, there are two types of links within a document. First, a link within a document can be to an * <em>external resource</em>, which is loaded automatically by the browser to augment that document (ie a link to an * image, style sheet, script, etc). Or, second, a link within a document can be a <em>hyperlink</em>, which, when * activated by the user, will cause the browser to stop displaying that document and navigate to displaying the * linked document instead. * </p> * * <p> * If the portal is configured to display a website to clients through this <code>ProxyChannel</code>, it is generally * expected that if the client navigates a hyperlink from one document to another within the proxied site, that the * linked document would also be rendered within the channel ({@linkplain net.www_eee.portal.Channel.Mode#VIEW view * mode}), and that any external resource links will continue to resolve correctly. Link rewriting is required for * each of these two scenarios to work. * </p> * * <p> * To continue rendering within {@linkplain net.www_eee.portal.Channel.Mode#VIEW view mode} while navigating between * website documents, any hyperlink from within a proxied document to another document within the * {@linkplain #getProxiedBaseURI(Page.Request) proxied site} will, by default, be rewritten to point back through * this channel (alternatively, hyperlinks may {@linkplain #isLinkRewritingHyperlinksToChannelDisabled(Page.Request) * optionally} be resolved into an {@linkplain URI#isAbsolute() absolute} link pointing directly back to their * {@linkplain #getProxiedBaseURI(Page.Request) origin/source location} instead). * </p> * * <p> * If this channel were to blindly return unmodified source HTML from a proxied document for aggregation into a * {@link Page}, any relative link would break when it was incorrectly resolved relative to the * {@link net.www_eee.portal.ContentDef.Page.Key#getPageURI(UriInfo, Map, String, boolean) URL} of that page, instead * of relative to the {@linkplain #BASE_URI_PROP base URL} of the document providing it. To avoid this, any relative * link to an external resource from within a proxied document will, by default, be resolved into an * {@linkplain URI#isAbsolute() absolute} link pointing directly back to the * {@linkplain #getProxiedBaseURI(Page.Request) origin/source location} for that resource (alternatively, resource * links may {@linkplain #isLinkRewritingResourceLinksToChannelEnabled(Page.Request) optionally} be rewritten to point * back through this channel using {@linkplain net.www_eee.portal.Channel.Mode#RESOURCE resource mode} instead). * </p> * * <p> * For link rewriting to work, the <code>ProxyChannel</code> obviously needs to know which attributes of a proxied * document constitute <em>links</em>. But since the implementation is generic, and doesn't actually understand any * particular dialect of markup language on it's own, <em>including HTML</em>, you will likely want to configure this * channel alongside a plugin which does, such as the * {@linkplain net.www_eee.portal.channelplugins.ProxyChannelHTMLSource HTML plugin}. * </p> * * @param pageRequest The {@link net.www_eee.portal.Page.Request Request} currently being processed. * @param proxiedFileURL The {@linkplain #getProxiedFileURL(Page.Request, Channel.Mode, boolean) proxied file URL}. * @param linkURI The {@link URI} of the link to rewrite. * @param hyperlink Is the <code>linkURI</code> a hyperlink? * @param absoluteURLRequired Does the result need to be {@linkplain URI#isAbsolute() absolute}? * @return A Map.Entry containing the rewritten link value, and a Boolean specifying if the returned link points back * through the channel. * @throws WWWEEEPortal.Exception If a problem occurred while determining the result. * @see #isLinkRewritingHyperlinksToChannelDisabled(Page.Request) * @see #isLinkRewritingResourceLinksToChannelEnabled(Page.Request) * @see net.www_eee.portal.channelplugins.ProxyChannelHTMLSource */ public Map.Entry<URI, Boolean> rewriteProxiedFileLink(final Page.Request pageRequest, final URL proxiedFileURL, final @Nullable URI linkURI, final boolean hyperlink, final boolean absoluteURLRequired) throws WWWEEEPortal.Exception { if ((linkURI != null) && (linkURI.isOpaque())) { return new AbstractMap.SimpleImmutableEntry<URI, Boolean>(linkURI, Boolean.FALSE); // Leave all the opaque ones alone (stuff like "mailto" links, etc), as we can't do anything with those. } final @NonNull URL resolvedLinkURL; // First, resolve the URL for the link so we know what server+file we are actually talking about here. try { if (linkURI == null) { resolvedLinkURL = proxiedFileURL; // An empty (null) link is equivalent to one back to the same proxied file. } else if (linkURI.isAbsolute()) { resolvedLinkURL = linkURI.toURL(); } else { resolvedLinkURL = new URL(proxiedFileURL, linkURI.toString()); // Resolve the link relative to the file it came from. } } catch (MalformedURLException mue) { throw new ContentManager.ContentException("Error resolving proxied link URL", mue); } if (((hyperlink) && (isLinkRewritingHyperlinksToChannelDisabled(pageRequest))) || ((!hyperlink) && (!isLinkRewritingResourceLinksToChannelEnabled(pageRequest)))) { // We are configured to not write this link back through the portal. return new AbstractMap.SimpleImmutableEntry<URI, Boolean>( rewriteProxiedFileLinkOutsideChannel(pageRequest, proxiedFileURL, linkURI, hyperlink, absoluteURLRequired, resolvedLinkURL), Boolean.FALSE); } /* * At this point, in order to determine what modifications to the link might be required, we need to figure out if * the link points to something either within, or outside of, the channel base URI's folder? */ if ((linkURI != null) && (linkURI.isAbsolute()) && (!equalHostAndPort(resolvedLinkURL, proxiedFileURL))) { // This is an absolute link which doesn't even point to the same server as the proxied file. return new AbstractMap.SimpleImmutableEntry<URI, Boolean>( rewriteProxiedFileLinkOutsideChannel(pageRequest, proxiedFileURL, linkURI, hyperlink, absoluteURLRequired, resolvedLinkURL), Boolean.FALSE); } /* * At this point we know the link at least points to the same server as the proxied file, but is it within the * channel base URI's folder? */ final String resolvedLinkPath = StringUtil.toString(StringUtil.mkNull(resolvedLinkURL.getPath()), "/"); final URI baseURI = getProxiedBaseURI(pageRequest); final URI resolvedBaseURI; if (baseURI.isAbsolute()) { resolvedBaseURI = baseURI; } else { resolvedBaseURI = ConfigManager.getContextResourceLocalHostURI(pageRequest.getUriInfo(), baseURI.getPath(), NetUtil.getQueryParams(baseURI), baseURI.getFragment(), true); } final String baseURIPath = resolvedBaseURI.getPath(); final String baseURIFolder; if ((baseURIPath.length() == 1) || (baseURIPath.charAt(baseURIPath.length() - 1) == '/')) { baseURIFolder = baseURIPath; // Path is a folder. } else { final int lastSlashIndex = baseURIPath.lastIndexOf('/'); baseURIFolder = (lastSlashIndex > 0) ? baseURIPath.substring(0, lastSlashIndex + 1) : String.valueOf('/'); } if (!resolvedLinkPath.startsWith(baseURIFolder)) { // We have determined this link is not within the channel base URI folder. return new AbstractMap.SimpleImmutableEntry<URI, Boolean>( rewriteProxiedFileLinkOutsideChannel(pageRequest, proxiedFileURL, linkURI, hyperlink, absoluteURLRequired, resolvedLinkURL), Boolean.FALSE); } /* * At this point we know the link points to within the channel base URI's folder, and that we need to rewrite it to * point back through the channel. */ final String linkChannelLocalPath = StringUtil.mkNull(resolvedLinkPath.substring(baseURIFolder.length())); final Mode channelMode = ((hyperlink) && (!isMaximizationDisabled(pageRequest))) ? Mode.VIEW : Mode.RESOURCE; final ContentDef.ChannelSpec<?> channelSpec = pageRequest.getChannelSpec(this); return new AbstractMap.SimpleImmutableEntry<URI, Boolean>( channelSpec.getKey().getChannelURI(pageRequest.getUriInfo(), channelMode, linkChannelLocalPath, (linkURI != null) ? NetUtil.getQueryParams(linkURI) : null, (linkURI != null) ? linkURI.getFragment() : null, absoluteURLRequired), Boolean.TRUE); }