so I am making a software for the eclipse, that tracks the changes made by the user, I have all the data available but now I need to put it into a cvs file located somewhere in the project folder, as the program should be able to be used by anyone without changing the file path.
ps the normal file path works, so I know that the code is alright, just don't seem to be able to print in the project folder.
try {
PrintWriter pw = new PrintWriter(new File("logger.csv"));
StringBuilder sb = new StringBuilder();
sb.append("time");
sb.append(",");
sb.append("action");
sb.append(",");
sb.append("info");
sb.append("\n");
sb.append("17:00");
sb.append(",");
sb.append("create");
sb.append(",");
sb.append("test");
sb.append("\n");
sb.append("17:40");
sb.append(",");
sb.append("del");
sb.append(",");
sb.append("test2");
sb.append("\n");
pw.write(sb.toString());
pw.close();
From an Eclipse plug-in you should use Eclipse's resource API to make sure resource changes are synchronized with the workspace:
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.NullProgressMonitor;
public class Foo {
public void bar() throws CoreException {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.run((ICoreRunnable) monitor -> {
IWorkspaceRoot root = workspace.getRoot();
IProject project = root.getProject("projectName");
IFile csv = project.getFile("logger.csv");
InputStream initialContent = new ByteArrayInputStream("time,action".getBytes());
csv.create(initialContent, true, new NullProgressMonitor());
});
}
}
See also Eclipse Wiki, Vogella and the Javadoc for further details.
Related
I'm creating a PhpStorm plugin with IntelliJ IDEA Community Edition and I would like to know how to create a file on disk from a PSIFile or VirtualFile.
Here my code: (The context is an action from NewGroup)
I've tried to use the PsiDirectory.copyFileFrom method to create the file but I have an exception com.intellij.util.IncorrectOperationException: Cannot copy non-physical file: PHP file
package fr.florent.idea.zendgenerator.action.NewGroup;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.util.ResourceUtil;
import com.jetbrains.php.lang.PhpFileType;
import fr.florent.idea.zendgenerator.action.AbstractDumbAwareAction;
import icons.PhpIcons;
import org.jetbrains.annotations.NotNull;
import java.net.URL;
public class CreateQueryAction extends AbstractDumbAwareAction {
public CreateQueryAction() {
super("Query", "Create query", PhpIcons.Php_icon);
}
#Override
public void actionPerformed(#NotNull AnActionEvent e) {
URL url = ResourceUtil.getResource(getClass(), "templates", "query.php"); // it contains an empty PHP class
VirtualFile virtualFile = VfsUtil.findFileByURL(url);
PsiFile file = PsiFileFactory.getInstance(e.getProject()).createFileFromText(
virtualFile.getPath(),
PhpFileType.INSTANCE,
LoadTextUtil.loadText(virtualFile)
);
PsiDirectory directory = LangDataKeys.IDE_VIEW.getData(e.getDataContext()).getOrChooseDirectory();
directory.copyFileFrom("query.php", file);
System.out.println("Create query");
}
}
I would like to have the file created in the project folder from the context of my action.
It will be great if someone can explain the process of creating a file in a IntelliJ plugin. I think the docs is really light.
In my case I would like to have the process to edit the query.php file, rename the class name, add method, properties, doc block and save it to the disk but I don't understand the PSI element.
You might want to ask this also on JB forum, there's a similar question: https://intellij-support.jetbrains.com/hc/en-us/community/posts/360001787320-Create-VirtualFile-or-PsiFile-from-content
The answer is:
final PsiFileFactory factory = PsiFileFactory.getInstance(project);
final PsiFile file = factory.createFileFromText(language, text);
i want to get files inside a folder when my application is running, so i know that i need to get it as resouce, if i will get it as file, it wont work, so it what i did.
jaxbContext = JAXBContext.newInstance(Catalogo.class);
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("catalogos/");
BufferedReader br = new BufferedReader(new InputStreamReader(resourceAsStream));
String line;
try {
while((line = br.readLine()) != null){
InputStream resourceAsStream1 = getClass().getClassLoader().getResourceAsStream("catalogos/"+line);
tempCat = (Catalogo) jaxbUnmarshaller.unmarshal(resourceAsStream1);
if(tempCat != null){
codigoCurso = String.valueOf(tempCat.getCourse().getId());
nomeDoCurso = dados.get(codigoCurso);
anoCatalogo = String.valueOf(tempCat.getAno());
if(nomeDoCurso == null){
dados.put(codigoCurso, tempCat.getCourse().getNome());
}
anos.add(anoCatalogo);
}
}
What i want to do is, get all files inside a folder (/catalogos/) and loop through and unmarshall each to an object so i will be able to access the property i need. So, when i run this with netbeans, works perfectly, but when i build and run the jar, i dont get the same result i've got using netbeans, i mean, the data is not where i expected.
The following example demonstrates how to get files from a directory in current runnable jar file and read these files contents.
Assume you have a NetBeans project with name "FolderTestApp". Do the following steps:
In your project root folder FolderTestApp\ create folder myFiles.
Copy your catalogos folder to the FolderTestApp\myFiles\
myFiles folder is necessary to preserve catalogos folder in your jar file structure when project jar is being generated. myFiles folder will disappear from jar file, but catalogos folder will remain.
If you don't do these steps, and place catalogos directly to the project folder (not as a child folder for myFiles), then your files from catalogos folder will be placed to the root of your jar file.
Add myFiles folder as a source folder in netbeans project properties.
Assume your property files contain the following contents:
file1.properties:
key11=value11
key12=value12
key13=value13
file2.properties:
key21=value21
key22=value22
key23=value23
Please note, that code below is not optimized. It is plain'n'dirty proof of concept to show, how to solve your task.
Add the following class to your project:
package folderapp;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.Properties;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class FolderTestApp {
public static void main(String[] args) throws URISyntaxException, IOException {
new FolderTestApp();
}
public FolderTestApp() throws URISyntaxException, IOException {
// determining the running jar file location
String jarFilePath = getClass().getProtectionDomain().
getCodeSource().getLocation().toURI().getPath();
// note, that the starting / is removed
// because zip entries won't start with this symbol
String zipEntryFolder = "catalogos/";
try (ZipInputStream zipInputStream
= new ZipInputStream(new FileInputStream(jarFilePath))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
System.out.println("processing: " + zipEntry.getName());
if (zipEntry.getName().startsWith(zipEntryFolder)) {
// directory "catalogos" will appear as a zip-entry
// and we're checking this condition
if (!zipEntry.isDirectory()) {
// adding symbol / because it is required for getResourceAsStream() call
printProperties("/" + zipEntry.getName());
}
}
zipEntry = zipInputStream.getNextEntry();
}
}
}
public void printProperties(String path) throws IOException {
try (InputStream is = getClass().getResourceAsStream(path)) {
InputStreamReader fr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(fr);
Properties properties = new Properties();
properties.load(br);
System.out.println("contents from: " + path + "\n");
Set<Object> keySet = properties.keySet();
for (Object key : keySet) {
System.out.println(key + " = " + properties.get(key));
}
System.out.println("---------------------------------------");
}
}
}
Set this class as the main class in your project settings (Run section).
And build your project via menu: Run - Build.
As your project has been built, open FolderTestApp/dist folder, where your generated jar is located and run this jar file:
That's it :)
It is possible to update individual files in a JAR file using the jar command as follows:
jar uf TicTacToe.jar images/new.gif
Is there a way to do this programmatically?
I have to rewrite the entire jar file if I use JarOutputStream, so I was wondering if there was a similar "random access" way to do this. Given that it can be done using the jar tool, I had expected there to be a similar way to do it programmatically.
It is possible to update just parts of the JAR file using Zip File System Provider available in Java 7:
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
public class ZipFSPUser {
public static void main(String [] args) throws Throwable {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
// locate file system by using the syntax
// defined in java.net.JarURLConnection
URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path externalTxtFile = Paths.get("/codeSamples/zipfs/SomeTextFile.txt");
Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");
// copy a file into the zip file
Files.copy( externalTxtFile,pathInZipfile,
StandardCopyOption.REPLACE_EXISTING );
}
}
}
Yes, if you use this opensource library you can modify it in this way as well.
https://truevfs.java.net
public static void main(String args[]) throws IOException{
File entry = new TFile("c:/tru6413/server/lib/nxps.jar/dir/second.txt");
Writer writer = new TFileWriter(entry);
try {
writer.write(" this is writing into a file inside an archive");
} finally {
writer.close();
}
}
I have images of codes that I want to decode. How can I use zxing so that I specify the image location and get the decoded text back, and in case the decoding fails (it will for some images, that's the project), it gives me an error.
How can I setup zxing on my Windows machine? I downloaded the jar file, but I don't know where to start. I understand I'll have to create a code to read the image and supply it to the library reader method, but a guide how to do that would be very helpful.
I was able to do it. Downloaded the source and added the following code. Bit rustic, but gets the work done.
import com.google.zxing.NotFoundException;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Reader;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.Result;
import com.google.zxing.LuminanceSource;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.*;
import com.google.zxing.qrcode.QRCodeReader;
class qr
{
public static void main(String args[])
{
Reader xReader = new QRCodeReader();
BufferedImage dest = null;
try
{
dest = ImageIO.read(new File(args[0]));
}
catch(IOException e)
{
System.out.println("Cannot load input image");
}
LuminanceSource source = new BufferedImageLuminanceSource(dest);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Vector<BarcodeFormat> barcodeFormats = new Vector<BarcodeFormat>();
barcodeFormats.add(BarcodeFormat.QR_CODE);
HashMap<DecodeHintType, Object> decodeHints = new HashMap<DecodeHintType, Object>(3);
decodeHints.put(DecodeHintType.POSSIBLE_FORMATS, barcodeFormats);
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = null;
try
{
result = xReader.decode(bitmap, decodeHints);
System.out.println("Code Decoded");
String text = result.getText();
System.out.println(text);
}
catch(NotFoundException e)
{
System.out.println("Decoding Failed");
}
catch(ChecksumException e)
{
System.out.println("Checksum error");
}
catch(FormatException e)
{
System.out.println("Wrong format");
}
}
}
The project includes a class called CommandLineRunner which you can simply call from the command line. You can also look at its source to see how it works and reuse it.
There is nothing to install or set up. It's a library. Typically you don't download the jar but declare it as a dependency in your Maven-based project.
If you just want to send an image to decode, use http://zxing.org/w/decode.jspx
In my auto updater application i am downloading a zipped file that contains the new MyApp.app application file. So i am downloading MyApp.zip.. Then i use this following class to try and unzip it:
package update;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class UnZip {
public static final void copyInputStream(InputStream in, OutputStream out)
throws IOException
{
byte[] buffer = new byte[1024];
int len;
while((len = in.read(buffer)) >= 0)
out.write(buffer, 0, len);
in.close();
out.close();
}
public static final void unZipIt(String F1, String F2) {
Enumeration entries;
ZipFile zipFile;
try {
zipFile = new ZipFile(F1);
entries = zipFile.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry)entries.nextElement();
if(entry.isDirectory()) {
// Assume directories are stored parents first then children.
System.err.println("Extracting directory: " + entry.getName());
// This is not robust, just for demonstration purposes.
(new File(entry.getName())).mkdirs();
continue;
}
System.err.println("Extracting file: " + entry.getName());
copyInputStream(zipFile.getInputStream(entry),
new BufferedOutputStream(new FileOutputStream(entry.getName())));
}
zipFile.close();
} catch (IOException ioe) {
System.err.println("Unhandled exception:");
ioe.printStackTrace();
return;
}
}
}
However after the unzip the application wont launch.. any ideas?
Your executable file is most likely not flagged as executable. The trick is that .app "files" are in fact directories, so making them executable serves no practical purpose, you need to find the actual binary.
To do that, you need to open ./myApp.app/Contents/Info.plit and look for the CFBundleExecutable key: the associated string is the path of the executable file, relative to ./myApp.app/Contents/MacOS, I believe.
Once you've found that file, chmod +x it, and check whether your application still fails to start.
If it doesn't, problem solved.
If it does, try and open your application from the terminal through the open ./myApp.app command. If anything odd is printed, update your question with it and let us know what that was.
If all else fails, look into the Console application for interesting log entries - you can search for your application's name, see if anything comes up.