What's the difference between URL.standardized and URL.absoluteURL? - swift

In Swift's URL class, there are .standardized and .absoluteURL properties (.standardizedURL and .absoluteURL, and .URLByStandardizingPath in Objective-C's NSURL). There's also .standardizedFileURL.
I have no idea what the difference is between all these, but there must be one since they provide all of them, right? I mean clearly the .standardizedFileURL is meant to only deal with file URLs, but other than that (for instance, if all are called on a file URL), what's the difference?
From the above-linked docs:
Swift
standardized
Returns a URL with any instances of “..” or “.” removed from its path.
absolute​URL
Returns the absolute URL.
Discussion
If the URL is itself absolute, this will return self.
standardized​File​URL
Standardizes the path of a file URL.
Discussion
If the is​File​URL is false, this method returns self.
Objective-C
standardized​URL
A copy of the URL with any instances of ".." or "." removed from its path. (read-only)
Discussion
This property contains a new NSURL object, initialized using the receiver’s path with any instances of ".." or "." removed. If the receiver does not conform to RFC 1808, this property contains nil.
absolute​URL
An absolute URL that refers to the same resource as the receiver. (read-only)
Discussion
If the URL is already absolute, this property contains a copy of the receiver. Resolution is performed per RFC 1808.
URLBy​Standardizing​Path
A URL that points to the same resource as the original URL using an absolute path. (read-only)
Discussion
This property only works on URLs with the file:​ path scheme. For all other URLs, it returns a copy of the original URL.
Like string​By​Standardizing​Path, this property can make the following changes in the provided URL:
Expand an initial tilde expression using string​By​Expanding​Tilde​In​Path.
Reduce empty components and references to the current directory (that is, the sequences “//” and “/./”) to single path separators.
In absolute paths only, resolve references to the parent directory (that is, the component “..”) to the real parent directory if possible using string​By​Resolving​Symlinks​In​Path, which consults the file system to resolve each potential symbolic link.
In relative paths, because symbolic links can’t be resolved, references to the parent directory are left in place.
Remove an initial component of “/private” from the path if the result still indicates an existing file or directory (checked by consulting the file system).
Note that the path contained by this property may still have symbolic link components in it. Note also that this property only works with file paths (not, for example, string representations of URLs).

If url is an absolute URL, url.absoluteURL == url.
If url is a relative URL and has a non-nil baseURL, then url.absoluteURL returns an absolute URL by resolving the relativity of url in the context of baseURL (and thus url.absoluteURL != url).
If url is a relative URL, url.standardized does not return an absolute URL, and may in fact return a URL that does not resolve the same way as url (!) because url.standardized removes any leading .. components of the path.
Example:
let base = URL(string: "https://stackoverflow.com/q/43258046/77567")!
// output: "https://stackoverflow.com/q/43258046/77567"
let rel = URL(string: "../16176911", relativeTo: base)!
// output: "../../16176911 -- ttps://stackoverflow.com/q/43258046/77567"
rel.absoluteURL
// output: "https://stackoverflow.com/q/16176911"
rel.standardized
// output: "16176911 -- ttps://stackoverflow.com/q/43258046/77567"
rel.standardized.absoluteURL
// output: "https://stackoverflow.com/q/43258046/16176911"

I think the key difference is that two URLs with different absolute paths may actually refer to the same resource, and in that case, they would have the same standardized URL. Examples of path elements that could cause this are:
~ vs /absolute/path/to/user/home/directory
paths that include soft links
/path/to/thing vs /path/to/other/../thing
etc.
The standardized url (URL.standardizedFileURL in swift) is very useful because two URLs that point to the same file should have the same standardizedFileURL even if they have different absolute paths. So one should generally use the standardized path if they wish to compare two file URLs.

Related

how to handle paths with openapi?

The structure of my node here in the company follow this sequence.
I have the app.js and all request will check my openapi /paths to see if there is a path that match my path in the url.
If there is no match I get a message path is not found.
But I need way to handle any path that isn't list in my openapi /paths instead of putting all path in the list.
for example I have 100 path 10 of them I will put explicit in the openapi paths all other (90) I want to handle without declaring in the in the openapi paths
I would like something like this:
paths:
/v1/client
/v1/product
...
...
/* for the 90 other paths
so when I call
localhost:3000/v1/client works fine
localhost:3000/vi/product works fine
this paths above will the treat for a specific function
localhost:3000/v1/anything doesn't work because isn't explict declared in my openapi paths.
I dont want to declare all other paths in the openapi. I want to forward all these other path to an spefic funtion.
thanks in advance.

Swift - How to modify file metadata like kMDItemDisplayName?

I'm trying to find a way to change a file's metadata attributes (those with the prefix of "kMDItem", listed by mdls), but I didn't find any solution for it. ToT
At first, I've tried using FileManager.default.setAttributes(_attributes:ofItemAtPath:), but this method only gives me few options, it only gives me ability to modify a file's modification date, creation date and posix permissions etc., which is not enough.
Then, I tried using NSMetadataItem with setValue(_value:forKey:) function to change the metadata value, this is my code:
var attributes = NSMetadataItem(url: URL(fileURLWithPath: "/path/to/file")
if let metadata = attributes {
metadata.setValue(newValue, forKey: kMDItemDisplayName as String)
metadata.setValue(newValue, forKey: NSMetadataItemDisplayNameKey)
// I've tried both of them from above (different keys), they both does not work at all
}
I noticed that setValue(_value:forKey:) does not do anything here by repeatedly getting this returning error: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
Finally, I red this post on StackOverflow, which led my way to this code:
_ = setxattr("/path/to/file".cString(using: .utf8), "kMDItemDisplayName", newValue.cString(using: .utf8), newValue.lengthOfBytes(using: .utf8), 0, 0)
After executing it, I used mdls and xattr -l to check the result, I realized that this is only the solution for adding extended attributes to a file, the metadata didn't change, only the extended attribute with the name of "kMDItemDisplayName" is successfully added.
The result is not what I want (I'm just using kMDItemDisplayName as an example for my question), I do not just want to find a way to add extended attributes to a file, but a way to edit the attributes listed by mdls. Maybe there is no solution for this? Or maybe I should do it in a completely different way?
Not all metadata can be changed. Much of it is not stored directly, it's derived or computed based on other metadata.
The display name for a simple file is derived from its name on disk and the system settings, like whether extensions are hidden or shown. The display name for a bundle (like an app) is slightly more complicated, but, assuming you don't find changing the contents of the bundle (which would break its code signature) acceptable, amounts to the same thing. Those are subject to the system language(s).
There are also certain folders whose names can be localized for display, but that's still based on their on-disk name.
So, to change a file's display name, change its actual name on disk.
For other properties, you can look at URL.setResourceValues(_:) and URLResourceValues to see which properties are settable. You can also look at URLResourceKey to see which are documented as "read-write".

How to map urls?

I would like to map pages such domain/content/myProject/home.html to domain/home.html. /content/myProject/ is not needed. I have the following code:
String newpath = getResourceResolver().map(page.getPath());
this does not change anything. newpath is stay page.getPath()
how to solve this issue?
Answering as this question as it remains unanswered. Here is an example of how the etc mappings should look like:
Trick is you add 2 entries to sling:internalRedirect as / and /content/example/
AEM first tries to resolve resources with first entry '/'. So non page URLs like /etc/designs, /content/dam etc will be addressed by the first entry. If it is unable to resolve using the first one, it uses the second entry to resolve the page.
This is also the adobe recommended way for URL shortening compared to other techniques like apache redirect.
You need to create map in etc.Then Resource Resolver will take care of trimming the path .
CREATING MAPPING DEFINITIONS IN AEM
In a standard installation of AEM you can find the folder:
/etc/map/http
This is the structure used when defining mappings for the HTTP protocol. Other folders (sling:Folder) can be created under /etc/map for any other protocols that you want to map.
Configuring an Internal Redirect to /content
To create the mapping that prefixes any request to http://localhost:4503/ with /content:
Using CRXDE navigate to /etc/map/http.
Create a new node:
Type sling:Mapping
This node type is intended for such mappings, though its use is not mandatory.
Name localhost_any
Click Save All.
Add the following properties to this node:
Name sling:match
Type String
Value localhost.4503/
Name sling:internalRedirect
Type String
Value /content/
Click Save All.
This will handle a request such as:
localhost:4503/geometrixx/en/products.html
as if:
localhost:4503/content/geometrixx/en/products.html
had been requested.
You can refer here for further documentation http://docs.adobe.com/docs/en/cq/5-6-1/deploying/resource_mapping.html

Data binding - getBindingContext() returns absolute path rather than relative

I've got a table which I'm firing an event on row selection. In the handler I want to get the context for the selected row and then create a new context for a lower level oData object and then bind that to a Text view.
I'm sure there is a beautifully succinct way of doing this but currently I am:
Getting the binding path and adding a string to create a path to my lower level object:
var path = oEvent.getParameters().listItem.getBindingContext().sPath + "/ComplianceNote";
This is returning a path with / as the first character, from what I understand this means it's the root object of the service or this is an "absolute" path. My current workaround is to remove the first character:
path = path.substr(1, path.length);
Then I can bind my Text view:
noteText.bindElement(path);
noteText.bindProperty("text", "Note");
This works fine but seems to me to be a code smell hacking around with the string. My questions are:
Why is the path returned as "absolute" rather than "relative"
What is the correct way to achieve this. I've been looking at things like setBindContext and bindText.
Cheers,
Gregor

Eclipse PDE: given a relative path like /ProjectName/lib/something.jar, how do you get a full filesystem path?

I'm trying to find a path to a jar file that's in the raw classpath. getRawClasspath returns a collection of IClasspathEntry objects. I can call getPath on those.
But getPath returns something weird: an IPath that starts with the project name, like:
/ProjectName/lib/something.jar
What's the right way to turn this relative path into a full-qualified OS path? At first I thought I could just add the path to the workspace root, but that doesn't work since there are often intermediate directories between the workspace and the project.
And more generally, how do I know what to do with an IPath returned by a method? It seems like I never know what that IPath is; relative to the project, relative to the workspace, relative to the project but with the project name as the first element, relative to the phase of the moon... It's all baffling, and the documentation is never helpful - or at least I don't know where to look.
UPDATE
I'm even more confused now. The problem still is that, when you have an IClasspathEntry, it's still unclear to me how to resolve it to a filesystem path.
The answer that says "if a path starts with a / it's an absolute path (relative to the workspace) isn't correct. The problem is that the getPath method on an IClasspath returns one of two things: a path starting with a slash that's relative to the workspace, or an IPath starting with a / that's an actual filesystem path. Yes, two completely different things are shoved into one type. You get the filesystem variant when the jar is outside the workspace, and you get the "absolute" variant when it's in the workspace.
I think part of the answer is that an IPath, by itself, is only a fancy string. You have to know where it came from to make sense out of it. It doesn't carry the right sorts of information to be useful on its own.
So what's the right way to deal with this?
try this:
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IResource res = root.findMember("/ProjectName/lib/something.jar");
System.out.println(res.getLocation().toString());
Paths in Eclipse are complicated, and there are a few other situations that you haven't mentioned, like classpath containers (JRE is an example), linked resources outside of the workspace and classpath variables.
To simplify, I suggest you use getResolvedClasspath instead, that returns only 'simple' classpath entires (no variables, no containers). According to its Javadoc, it returns absolute paths, and their interpretation depends on the kind of the entry:
CPE_LIBRARY - if it's an external library, it's a filesystem path (and it has no associated resource, meaning you can't find it with findMember). Otherwise, it's a path based on the workspace root
CPE_PROJECT - absolute path to the project
CPE_SOURCE - absolute path to the source folder
All absolute path are interpreted in the workspace. If you need the file-system path, you need to go through getLocation.
As a side-note, there is no 1-to-1 mapping between file-system entities and workspace resources. Because of workspace links, you may have several workspace paths pointing to the same (file-system) location.
This is the best I could come up with, and it totally is an ugly hack, yes:
private IPath getCorrectAbsolutePath(IJavaProject project, IPath path) throws IllegalArgumentException {
final String projectName = project.getProject().getName();
if (path.segmentCount() > 1 && path.segment(0).equals(projectName)) {
IPath projectAbsolutePath = project.getProject().getLocation();
IPath relativePath = path.removeFirstSegments(1);
return projectAbsolutePath.append(relativePath);
} else {
if (!path.isAbsolute())
path = path.makeAbsolute();
if (!path.isAbsolute())
throw new IllegalArgument("Cannot make IPath absolute: " + path.toString());
return path;
}
}
I have a suggestion, look picture attachment, find "location" property from properties of any plugin of eclipse , maybe can find it where is from. but sorry I have no 10 reputation, you can see picture from picture url