JGit's Status doesn't list any files when it should - jgit

I wrote a Spock test to learn how to use JGit. The general idea of the test follows these steps:
Create a "TestRepo" directory
Initialize a new Git repository there ("TestRepo/.git")
Create a new File in the parent directory (TestRepo) and set its text to something to take up space
Call "git status"
(debug) Groovy dump the returned Status object
Assert that the returned Status object has the file listed as untracked.
When I run the below test, it fails. Why?
state.dump() prints
Status#38989dff
diff=org.eclipse.jgit.lib.IndexDiff#72def3cd
clean=true
hasUncommittedChanges=false
Code below:
class GitActionsSpec extends Specification {
public static final ROOT_DIR_PATH = Paths.get(System.getProperty("user.home"), "TestRepo")
public static final ROOT_DIR_STRING = ROOT_DIR_PATH.toString()
public static final GIT_DIR_PATH = ROOT_DIR_PATH.resolve(".git")
#Shared
Git git
/**
* Creates a repository in rootDirPath
*/
def setupSpec() {
if (Files.exists(ROOT_DIR_PATH)) {
deleteDirectory(ROOT_DIR_PATH)
}
Files.createDirectory(ROOT_DIR_PATH)
/*
GitActions.createRepoIn(File parentDirectory) {
return Git.init().setDirectory(f).call()
}
*/
git = GitActions.createRepoIn(ROOT_DIR_PATH.toFile())
assert git.repository.getDirectory().exists()
}
// The actual test
def "A newly-created file should be listed as 'untracked'"() {
given: "A new file"
Path file = ROOT_DIR_PATH.relativize(ROOT_DIR_PATH.resolve("file.txt"))
file.text = "filler text"
assert Files.exists(file)
when: "user requests the status"
Status state = git.status().addPath(file.toString()).call()
then: "Git lists that file as untracked"
println state.dump()
!state.getUntracked().isEmpty()
}
def cleanupSpec() {
git.close()
deleteDirectory(ROOT_DIR_PATH)
}
def deleteDirectory(Path directory) {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
#Override
FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir)
return FileVisitResult.CONTINUE
}
#Override
FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file)
return FileVisitResult.CONTINUE
}
})
}
}

Turns out the issue lied in the code that sets up file.
File's toString() returns A, not B:
A: /home/user/Project/Module/file.txt
B: /home/user/TestRepo/file.txt

Related

JavaFX - tableview shows data but when saving to file, the file is empty

In my program I read a config file (.txt file) and show the content in a tableview. That works.
Tableview with data
The second column can be edited. This serves as a config file for the program.
If I now save the data (File - Save) the config file is empty. I have no idea, why. Here is the code:
File - Save calls this:
#FXML
public void saveConfig() throws IOException {
System.out.println("File - Save clicked");
SCDConfigDataAccess configData = new SCDConfigDataAccess();
configData.saveData(SCDController.configFile);
closeConfig();
}//saveConfig
and configData.saveData does this:
public class SCDConfigDataAccess {
private static ObservableList<SCDConfigData> scdConfig;
public void saveData(File configFile) throws IOException {
BufferedWriter bw = Files.newBufferedWriter(Paths.get(configFile.getPath()));
String output = "";
System.out.println("File: " + configFile.getPath());
try {
for (SCDConfigData data : scdConfig) {
output = data.getsConfigType() + "=" + data.getsConfigValue() + "\n";
System.out.println("Data: " + output);
bw.write(output); }
bw.flush();
bw.close();
}catch(IOException e){ System.out.println("Error: " + e.getMessage()); }
} //saveData
}//class
I get these messages:
File - Save clicked
File: C:\Users\Michael\AppData\Local\SCD\scdconfig.ini
These are expected and correct.
I do not get a message out of the for-loop. That lets me think there is no data. But why? I see the data.
I'm sure I'm just missing a little thing. Any help is appreciated.
The config file was 127 bytes when I read it and is now 0.
Thanks,
Michael
I figured it out. The problem was this line of code in the method saveConfig() of the controller
SCDConfigDataAccess configData = new SCDConfigDataAccess();
This creates a new instance and this does not have a connection to the data. Instead of doing this I use the instance defined in the controller class itself like so:
public class SCDConfigController {
private SCDConfigDataAccess configDataAccess;
public void saveConfig() throws IOException {
configDataAccess.saveData(SCDController.configFile);
closeConfig();
}//saveConfig
And this of course works.

JcrExportCommand filter to exclude "mgnl:page" in magnolia cms

I would like filter out "mgnl:page" nodes for the JcrExportCommand in magnolia when I execute it on a node with a custom action.
The filter I wrote in the code below doesn't work. It still gives me mgnl:page children nodes in the exported file.
//set filter to only export mgnl:area subnodes
DefaultFilter filter = new JcrExportCommand.DefaultFilter();
NodeFilteringPredicate nodePredicate = new NodeFilteringPredicate();
nodePredicate.setNodeTypes(Lists.newArrayList("mgnl:area"));
filter.setNodePredicate(nodePredicate);
How do I set the correct filter to export everything but "mgnl:page" subnodes? I believed that setting the NodeFilteringPredicate to "mgnl:area" I get only nodes that are of that type.
You have to set the filter on JcrExportCommand for it to take effect:
DefaultFilter filter = new DefaultFilter();
filter.getNodePredicate().getNodeTypes().add("mgnl:page");
jcrExport.setFilter(Collections.singletonMap("website", filter));
* this is not the answer to my question but instead the answer to a comment since code is not properly formated in a comment *
As #michid suggested I created a custom Predicator and used JcrExportCommand.DefaultFilter#setNodePredicate()to apply it.
I am expecting to get an exported YAML with filtered nodes according to the Predicate but instead I am still getting all the nodes (including children of type mgnl:page).
My custom Predicate class is:
public class MyPredicate extends NodeFilteringPredicate {
public boolean evaluate(Node node) throws AccessDeniedException, ItemNotFoundException, RepositoryException {
//only nodes that are not of type mgnl:page
if((node.getParent().getPrimaryNodeType().getName().contains("mgnl:page"))&&(node.getPrimaryNodeType().getName().contains("mgnl:page"))) {
return false;
}else{
return true;
}
}
}
My custom Action class is:
public class MyAction extends AbstractMultiItemAction<UzhVersioning> {
private AbstractPredicate<Node> MyPredicate;
public MyAction(xxxVersioning definition, JcrItemAdapter item, UiContext uiContext) {
super(definition, item, uiContext);
// TODO Auto-generated constructor stub
}
#Override
public void execute() {
//export nodes from a JCR workspace
JcrExportCommand exporter = new JcrExportCommand();
//sets export format to yaml
exporter.setFormat("yaml");
exporter.setRepository("website");
//set filter to only export top mgnl:page and its mgnl:area nodes
DefaultFilter filter = new JcrExportCommand.DefaultFilter();
AbstractPredicate<Node> predicate = new MyPredicate();
filter.setNodePredicate(predicate);
exporter.setFilters(Collections.singletonMap("website", filter));
//setup the root directory for exports
File rootDir = new File("/Users/asusti/Downloads/yamlExport");
// clean up first
rootDir.delete();
rootDir.mkdirs();
//get root node
Node node = (Node) getItems().get(0).getJcrItem();
try {
//set export path
exporter.setPath(node.getPath());
File file = new File(rootDir, node.getName()+".yaml");
FileOutputStream out = new FileOutputStream(file);
exporter.setOutputStream(out);
exporter.execute(MgnlContext.getInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Generate Parser for a File with JavaCC

I am a beginner with JavaCC,and i'm trying to generate a file Parser.
I have already been able to generate a successful parser interpenetrated a line that is entered on the keyboard.
Parser example when I enter the keyboard "First Name: William", I managed to display on the screen the name of the variable and the value.
Now I have a file .txt who contain a large number of names and their value, and I would like to successfully display them on the screen.
below is my .jj file that I have already written to generate a parser of a typed line
Now i want the same but for a file.
options
{
static = true;
}
PARSER_BEGIN(parser_name)
public class parser_name
{
public static void main(String args []) throws ParseException
{
System.out.println("Waiting for the Input:");
parser_name parser = new parser_name(System.in);
parser.Start();
}
}
PARSER_END(parser_name)
SKIP :
{
" "
| "\r"
| "\t"
| "\n"
}
TOKEN : { < DIGIT : (["0"-"9"])+ > }
TOKEN : { <VARIABLE: (["a"-"z", "A"-"Z"])+> }
TOKEN : { <VALUE: (~["\n",":"])+> }
TOKEN : { <ASSIGNMENT: ":"> }
void Start(): { Token t,t1,t2;}
{
t=<VARIABLE>
t1=<ASSIGNMENT>
t2=<VALUE>
{ System.out.println("The Variable is "+t.image+",and the Value is "+t2.image); }
}
I have already tried to replace the "System.in" at the parser constructor with an object of type File.And then read the file by line, but it did not work.
Pass a Reader to the parser's constructor.

AspectJ - Is is possible to extend an enum's value?

Say I have an enum
public enum E {A,B,C}
Is it possible to add another value, say D, by AspectJ?
After googling around, it seems that there used to be a way to hack the private static field $VALUES, then call the constructor(String, int) by reflection, but seems not working with 1.7 anymore.
Here are several links:
http://www.javaspecialists.eu/archive/Issue161.html (provided by #WimDeblauwe )
and this: http://www.jroller.com/VelkaVrana/entry/modify_enum_with_reflection
Actually, I recommend you to refactor the source code, maybe adding a collection of valid region IDs to each enumeration value. This should be straightforward enough for subsequent merging if you use Git and not some old-school SCM tool like SVN.
Maybe it would even make sense to use a dynamic data structure altogether instead of an enum if it is clear that in the future the list of commands is dynamic. But that should go into the upstream code base. I am sure the devs will accept a good patch or pull request if prepared cleanly.
Remember: Trying to avoid refactoring is usually a bad smell, a symptom of an illness, not a solution. I prefer solutions to symptomatic workarounds. Clean code rules and software craftsmanship attitude demand that.
Having said the above, now here is what you can do. It should work under JDK 7/8 and I found it on Jérôme Kehrli's blog (please be sure to add the bugfix mentioned in one of the comments below the article).
Enum extender utility:
package de.scrum_master.util;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
public class DynamicEnumExtender {
private static ReflectionFactory reflectionFactory =
ReflectionFactory.getReflectionFactory();
private static void setFailsafeFieldValue(Field field, Object target, Object value)
throws NoSuchFieldException, IllegalAccessException
{
// let's make the field accessible
field.setAccessible(true);
// next we change the modifier in the Field instance to
// not be final anymore, thus tricking reflection into
// letting us modify the static final field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
// blank out the final bit in the modifiers int
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
fa.set(target, value);
}
private static void blankField(Class<?> enumClass, String fieldName)
throws NoSuchFieldException, IllegalAccessException
{
for (Field field : Class.class.getDeclaredFields()) {
if (field.getName().contains(fieldName)) {
AccessibleObject.setAccessible(new Field[] { field }, true);
setFailsafeFieldValue(field, enumClass, null);
break;
}
}
}
private static void cleanEnumCache(Class<?> enumClass)
throws NoSuchFieldException, IllegalAccessException
{
blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
blankField(enumClass, "enumConstants"); // IBM JDK
}
private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes)
throws NoSuchMethodException
{
Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
parameterTypes[0] = String.class;
parameterTypes[1] = int.class;
System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
return reflectionFactory.newConstructorAccessor(enumClass .getDeclaredConstructor(parameterTypes));
}
private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues)
throws Exception
{
Object[] parms = new Object[additionalValues.length + 2];
parms[0] = value;
parms[1] = Integer.valueOf(ordinal);
System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
}
/**
* Add an enum instance to the enum class given as argument
*
* #param <T> the type of the enum (implicit)
* #param enumType the class of the enum to be modified
* #param enumName the name of the new enum instance to be added to the class
*/
#SuppressWarnings("unchecked")
public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName) {
// 0. Sanity checks
if (!Enum.class.isAssignableFrom(enumType))
throw new RuntimeException("class " + enumType + " is not an instance of Enum");
// 1. Lookup "$VALUES" holder in enum class and get previous enum
// instances
Field valuesField = null;
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields) {
if (field.getName().contains("$VALUES")) {
valuesField = field;
break;
}
}
AccessibleObject.setAccessible(new Field[] { valuesField }, true);
try {
// 2. Copy it
T[] previousValues = (T[]) valuesField.get(enumType);
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
// 3. build new enum
T newValue = (T) makeEnum(
enumType, // The target enum class
enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
values.size(), new Class<?>[] {}, // could be used to pass values to the enum constuctor if needed
new Object[] {} // could be used to pass values to the enum constuctor if needed
);
// 4. add new value
values.add(newValue);
// 5. Set new values field
setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
// 6. Clean enum cache
cleanEnumCache(enumType);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
}
Sample application & enum:
package de.scrum_master.app;
/** In honour of "The Secret of Monkey Island"... ;-) */
public enum Command {
OPEN, CLOSE, PUSH, PULL, WALK_TO, PICK_UP, TALK_TO, GIVE, USE, LOOK_AT, TURN_ON, TURN_OFF
}
package de.scrum_master.app;
public class Server {
public void executeCommand(Command command) {
System.out.println("Executing command " + command);
}
}
package de.scrum_master.app;
public class Client {
private Server server;
public Client(Server server) {
this.server = server;
}
public void issueCommand(String command) {
server.executeCommand(
Command.valueOf(
command.toUpperCase().replace(' ', '_')
)
);
}
public static void main(String[] args) {
Client client = new Client(new Server());
client.issueCommand("use");
client.issueCommand("walk to");
client.issueCommand("undress");
client.issueCommand("sleep");
}
}
Console output with original enum:
Executing command USE
Executing command WALK_TO
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant de.scrum_master.app.Command.UNDRESS
at java.lang.Enum.valueOf(Enum.java:236)
at de.scrum_master.app.Command.valueOf(Command.java:1)
at de.scrum_master.app.Client.issueCommand(Client.java:12)
at de.scrum_master.app.Client.main(Client.java:22)
Now you can either add an aspect with an advice executed after the enum class was loaded or just call this manually in your application before extended enum values are to be used for the first time. Here I am showing how it can be done in an aspect.
Enum extender aspect:
package de.scrum_master.aspect;
import de.scrum_master.app.Command;
import de.scrum_master.util.DynamicEnumExtender;
public aspect CommandExtender {
after() : staticinitialization(Command) {
System.out.println(thisJoinPoint);
DynamicEnumExtender.addEnum(Command.class, "UNDRESS");
DynamicEnumExtender.addEnum(Command.class, "SLEEP");
DynamicEnumExtender.addEnum(Command.class, "WAKE_UP");
DynamicEnumExtender.addEnum(Command.class, "DRESS");
}
}
Console output with extended enum:
staticinitialization(de.scrum_master.app.Command.<clinit>)
Executing command USE
Executing command WALK_TO
Executing command UNDRESS
Executing command SLEEP
Et voilà! ;-)

FileStatus use to recurse directory

I have following directory structure,
Dir1
|___Dir2
|___Dir3
|___Dir4
|___File1.gz
|___File2.gz
|___File3.gz
The subdirectories are just nested and donot contain any files
I am trying to use the following for recursing through a directory on HDFS.If its a directory I append /* to the path and addInputPath
arg[0] = "path/to/Dir1"; // given at command line
FileStatus fs = new FileStatus();
Path q = new Path(args[0]);
FileInputFormat.addInputPath(job,q);
Path p = new Path(q.toString()+"/*");
fs.setPath(p);
while(fs.isDirectory())
{
fs.setPath(new Path(p.toString()+"/*"));
FileInputFormat.addInputPath(job,fs.getPath());
}
But the code doesnt seem to go in the while loop and I get not a File Exception
Where is the if statement you are referring to?
Anyway, you may have a look at these utility methods which add all files within a directory to a job's input:
Utils:
public static Path[] getRecursivePaths(FileSystem fs, String basePath)
throws IOException, URISyntaxException {
List<Path> result = new ArrayList<Path>();
basePath = fs.getUri() + basePath;
FileStatus[] listStatus = fs.globStatus(new Path(basePath+"/*"));
for (FileStatus fstat : listStatus) {
readSubDirectory(fstat, basePath, fs, result);
}
return (Path[]) result.toArray(new Path[result.size()]);
}
private static void readSubDirectory(FileStatus fileStatus, String basePath,
FileSystem fs, List<Path> paths) throws IOException, URISyntaxException {
if (!fileStatus.isDir()) {
paths.add(fileStatus.getPath());
}
else {
String subPath = fileStatus.getPath().toString();
FileStatus[] listStatus = fs.globStatus(new Path(subPath + "/*"));
if (listStatus.length == 0) {
paths.add(fileStatus.getPath());
}
for (FileStatus fst : listStatus) {
readSubDirectory(fst, subPath, fs, paths);
}
}
}
Use it in your job runner class:
...
Path[] inputPaths = Utils.getRecursivePaths(fs, inputPath);
FileInputFormat.setInputPaths(job, inputPaths);
...

Resources