Java & symbolic links in windows - java

I've been playing with java.nio.file.Files and stumbled upon a strange issue. I have a symbolic link, but Files.isSymbolicLink() and symbolic link attribute of Files.readAttributes() show different results.
Here's how I create the link:
D:\DEV\test>mklink /D link1 components
symbolic link created for link1 <<===>> components
Relevant java code:
Path symLinkDirectory = Paths.get("D:\\DEV\\test\\link1");
DosFileAttributes dosFileAttributes = Files.readAttributes(symLinkDirectory, DosFileAttributes.class);
System.out.println(String.format(
"Files.isSymbolicLink(): %b, dosFileAttributes.isSymbolicLink(): %b",
Files.isSymbolicLink(symLinkDirectory), dosFileAttributes.isSymbolicLink()));
Gives me this output:
Files.isSymbolicLink(): true, dosFileAttributes.isSymbolicLink(): false
Could anyone tell me why attributes report that the file is not a symbolic link? Am I missing something? Is this happening on unix too?

You need to add LinkOption.NOFOLLOW_LINKS to the invocation of readAttributes to get the attributes of the link itself instead of the link target.
DosFileAttributes dosFileAttributes = Files.readAttributes(symLinkDirectory,
DosFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

Related

How to automatically commit only src folder (and its content) of each projects with SVN [duplicate]

If I had 20 directories under trunk/ with lots of files in each and only needed 3 of those directories, would it be possible to do a Subversion checkout with only those 3 directories under trunk?
Indeed, thanks to the comments to my post here, it looks like sparse directories are the way to go. I believe the following should do it:
svn checkout --depth empty http://svnserver/trunk/proj
svn update --set-depth infinity proj/foo
svn update --set-depth infinity proj/bar
svn update --set-depth infinity proj/baz
Alternatively, --depth immediates instead of empty checks out files and directories in trunk/proj without their contents. That way you can see which directories exist in the repository.
As mentioned in #zigdon's answer, you can also do a non-recursive checkout. This is an older and less flexible way to achieve a similar effect:
svn checkout --non-recursive http://svnserver/trunk/proj
svn update trunk/foo
svn update trunk/bar
svn update trunk/baz
Subversion 1.5 introduces sparse checkouts which may be something you might find useful. From the documentation:
... sparse directories (or shallow checkouts) ... allows you to easily check out a working copy—or a portion of a working copy—more shallowly than full recursion, with the freedom to bring in previously ignored files and subdirectories at a later time.
I wrote a script to automate complex sparse checkouts.
#!/usr/bin/env python
'''
This script makes a sparse checkout of an SVN tree in the current working directory.
Given a list of paths in an SVN repository, it will:
1. Checkout the common root directory
2. Update with depth=empty for intermediate directories
3. Update with depth=infinity for the leaf directories
'''
import os
import getpass
import pysvn
__author__ = "Karl Ostmo"
__date__ = "July 13, 2011"
# =============================================================================
# XXX The os.path.commonprefix() function does not behave as expected!
# See here: http://mail.python.org/pipermail/python-dev/2002-December/030947.html
# and here: http://nedbatchelder.com/blog/201003/whats_the_point_of_ospathcommonprefix.html
# and here (what ever happened?): http://bugs.python.org/issue400788
from itertools import takewhile
def allnamesequal(name):
return all(n==name[0] for n in name[1:])
def commonprefix(paths, sep='/'):
bydirectorylevels = zip(*[p.split(sep) for p in paths])
return sep.join(x[0] for x in takewhile(allnamesequal, bydirectorylevels))
# =============================================================================
def getSvnClient(options):
password = options.svn_password
if not password:
password = getpass.getpass('Enter SVN password for user "%s": ' % options.svn_username)
client = pysvn.Client()
client.callback_get_login = lambda realm, username, may_save: (True, options.svn_username, password, True)
return client
# =============================================================================
def sparse_update_with_feedback(client, new_update_path):
revision_list = client.update(new_update_path, depth=pysvn.depth.empty)
# =============================================================================
def sparse_checkout(options, client, repo_url, sparse_path, local_checkout_root):
path_segments = sparse_path.split(os.sep)
path_segments.reverse()
# Update the middle path segments
new_update_path = local_checkout_root
while len(path_segments) > 1:
path_segment = path_segments.pop()
new_update_path = os.path.join(new_update_path, path_segment)
sparse_update_with_feedback(client, new_update_path)
if options.verbose:
print "Added internal node:", path_segment
# Update the leaf path segment, fully-recursive
leaf_segment = path_segments.pop()
new_update_path = os.path.join(new_update_path, leaf_segment)
if options.verbose:
print "Will now update with 'recursive':", new_update_path
update_revision_list = client.update(new_update_path)
if options.verbose:
for revision in update_revision_list:
print "- Finished updating %s to revision: %d" % (new_update_path, revision.number)
# =============================================================================
def group_sparse_checkout(options, client, repo_url, sparse_path_list, local_checkout_root):
if not sparse_path_list:
print "Nothing to do!"
return
checkout_path = None
if len(sparse_path_list) > 1:
checkout_path = commonprefix(sparse_path_list)
else:
checkout_path = sparse_path_list[0].split(os.sep)[0]
root_checkout_url = os.path.join(repo_url, checkout_path).replace("\\", "/")
revision = client.checkout(root_checkout_url, local_checkout_root, depth=pysvn.depth.empty)
checkout_path_segments = checkout_path.split(os.sep)
for sparse_path in sparse_path_list:
# Remove the leading path segments
path_segments = sparse_path.split(os.sep)
start_segment_index = 0
for i, segment in enumerate(checkout_path_segments):
if segment == path_segments[i]:
start_segment_index += 1
else:
break
pruned_path = os.sep.join(path_segments[start_segment_index:])
sparse_checkout(options, client, repo_url, pruned_path, local_checkout_root)
# =============================================================================
if __name__ == "__main__":
from optparse import OptionParser
usage = """%prog [path2] [more paths...]"""
default_repo_url = "http://svn.example.com/MyRepository"
default_checkout_path = "sparse_trunk"
parser = OptionParser(usage)
parser.add_option("-r", "--repo_url", type="str", default=default_repo_url, dest="repo_url", help='Repository URL (default: "%s")' % default_repo_url)
parser.add_option("-l", "--local_path", type="str", default=default_checkout_path, dest="local_path", help='Local checkout path (default: "%s")' % default_checkout_path)
default_username = getpass.getuser()
parser.add_option("-u", "--username", type="str", default=default_username, dest="svn_username", help='SVN login username (default: "%s")' % default_username)
parser.add_option("-p", "--password", type="str", dest="svn_password", help="SVN login password")
parser.add_option("-v", "--verbose", action="store_true", default=False, dest="verbose", help="Verbose output")
(options, args) = parser.parse_args()
client = getSvnClient(options)
group_sparse_checkout(
options,
client,
options.repo_url,
map(os.path.relpath, args),
options.local_path)
Or do a non-recursive checkout of /trunk, then just do a manual update on the 3 directories you need.
If you already have the full local copy, you can remove unwanted sub folders by using --set-depth command.
svn update --set-depth=exclude www
See: http://blogs.collab.net/subversion/sparse-directories-now-with-exclusion
The set-depth command support multipile paths.
Updating the root local copy will not change the depth of the modified folder.
To restore the folder to being recusively checkingout, you could use --set-depth again with infinity param.
svn update --set-depth=infinity www
I'm adding this information for those using the TortoiseSvn tool: to obtain the OP same functionality, you can use the Choose items... button in the Checkout Depth section of the Checkout function, as shown in the following screenshot:
Sort of. As Bobby says:
svn co file:///.../trunk/foo file:///.../trunk/bar file:///.../trunk/hum
will get the folders, but you will get separate folders from a subversion perspective. You will have to go separate commits and updates on each subfolder.
I don't believe you can checkout a partial tree and then work with the partial tree as a single entity.
Not in any especially useful way, no. You can check out subtrees (as in Bobby Jack's suggestion), but then you lose the ability to update/commit them atomically; to do that, they need to be placed under their common parent, and as soon as you check out the common parent, you'll download everything under that parent. Non-recursive isn't a good option, because you want updates and commits to be recursive.

Disable name prefix in javadoc

When generating the Javadoc, it adds on prefix to the imported class name, as shown below on the first line 'java.lang'.
How to properly disable that?
Have tried adding -noqualifier in Other command line arguments in my IntelliJ popup window but the following error occurred:
javadoc: error - Illegal package name: "/Users"
Below is a snippet from the Javadoc I generated:
public TrainRoute(java.lang.String name,
int routeNumber)
Creates a new TrainRoute with the given name and number.
Should meet the specification of Route.Route(String, int)
Parameters:
name - The name of the route.
routeNumber - The route number of the route.
I know this is an old question, but still relevant. I am aware of two solution which can be used alone or in combination:
To suppress prefixes on java packages use:
-noqualifier java.*
To suppress prefixes and link to the actual Java docs use:
-link https://docs.oracle.com/javase/8/docs/api
Both suppress the java name qualifiers. The second also links to the Oracle docs.
See javadoc options docs for more info.

Where does ClassLoader.getSystemResource() go to?

There is existing code that has a call
URL resource = ClassLoader.getSystemResource("hp.obo.gz");
From my understanding, this searches the classpath for the requested file. I printed out the classpath using the code from here: https://www.mkyong.com/java/how-to-print-out-the-current-project-classpath/
and got the following:
/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202017.1.3/lib/idea_rt.jar
/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202017.1.3/plugins/junit/lib/junit-rt.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/charsets.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/deploy.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/access-bridge-64.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/cldrdata.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/dnsns.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/jaccess.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/jfxrt.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/localedata.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/nashorn.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/sunec.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/sunjce_provider.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/sunmscapi.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/sunpkcs11.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/ext/zipfs.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/javaws.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/jce.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/jfr.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/jfxswt.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/jsse.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/management-agent.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/plugin.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/resources.jar
/C:/Program%20Files/Java/jdk1.8.0_66/jre/lib/rt.jar
/C:/Users/johnp/Desktop/git_stuff/boqa/target/test-classes/
/C:/Users/johnp/Desktop/git_stuff/boqa/target/classes/
/C:/Users/johnp/.m2/repository/commons-cli/commons-cli/1.2/commons-cli-1.2.jar
/C:/Users/johnp/.m2/repository/de/charite/compbio/ontologizer-core/2.1-SNAPSHOT/ontologizer-core-2.1-20160115.222100-6.jar
/C:/Users/johnp/.m2/repository/com/att/research/grappa/1.2.1/grappa-1.2.1.jar
/C:/Users/johnp/.m2/repository/de/charite/compbio/ontologizer-benchmark/2.1-SNAPSHOT/ontologizer-benchmark-2.1-20160115.222106-6.jar
/C:/Users/johnp/.m2/repository/com/beust/jcommander/1.35/jcommander-1.35.jar
/C:/Users/johnp/.m2/repository/org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar
/C:/Users/johnp/.m2/repository/org/apache/logging/log4j/log4j-1.2-api/2.8.2/log4j-1.2-api-2.8.2.jar
/C:/Users/johnp/.m2/repository/org/apache/logging/log4j/log4j-api/2.8.2/log4j-api-2.8.2.jar
/C:/Users/johnp/.m2/repository/org/apache/logging/log4j/log4j-core/2.8.2/log4j-core-2.8.2.jar
/C:/Users/johnp/.m2/repository/junit/junit/4.12/junit-4.12.jar
/C:/Users/johnp/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202017.1.3/lib/idea_rt.jar
However, where it actually is found is here (deleting hp.obo.gz causes a null pointer exception):
C:\Users\johnp\Desktop\git_stuff\boqa\src\main\resources
I don't see how it got this location given the above output (it seems similar to /C:/Users/johnp/Desktop/git_stuff/boqa/target/test-classes/
and
/C:/Users/johnp/Desktop/git_stuff/boqa/target/classes/). Any help would be appreciated. Thanks!
Right click on a folder and "mark directory as" -> "Resources Root". This will configure everything behind the scenes in IntelliJ to work

Maven. Nested properties filtering doesn't work

I have two property files:
#environment.properties
env = production
and second file is:
#commons.properties
production.port = 123
test.port = 567
Also,I have resource file which need be filtered by environment.properties file and commons.properties file and copied.
The resource-file contains:
${${env}.port}
So,I want to filter my resource file with first file and get:
${production.port}
and then I want to filter it with second filter file and get:
123
I use maven 3.2.5 and the resource-file isn't filtered at all.
I know that there's issue related with this problem:
https://jira.codehaus.org/browse/MRESOURCES-70 But it still unresolved.
So,my question is - is there any solution to resolve this problem? (actually,I think that resource-plugin should be modified for work with nested property filtering).
And second question - does exist any way to avoid this problem by refactoring,I mean any other architecture solution. Or, what would you do if you had same problem?

About Path normalize() in Java

For the following code, the aPath turns out to be D:\ OCPJP7\ NIO2\ src\SubPath.java. Why is the programs element gone?
Path aPath = Paths.get(" D:\\ OCPJP7\\ programs\\..\\ NIO2\\ src\\.\\ SubPath.java");
aPath = aPath.normalize();
Because the normalization replaced the .. programs' parent directory.
So you have NIO2 as a sub-folder of OCPJP7.
Similarly, . goes away as it's redundant (indicates current directory within context).
Because the programs element is followed by \\..\\ which means "to go up one directory level". This sequence removes the \\programs\\ part from your path.

Categories

Resources