I want to run an action (with a rule) when a file enters the folder in my alfresco repository. The file needs to be moved to a new folder. The new folder will be named after the metadata property "subject" from the file I uploaded.
I am not able to figure out how to do this. Who got any tips?
(A repository webscript is also an option).
This is how I see it:
import java.util.List;
public class MoveExecuter extends ActionExecuterAbstractBase {
public static final String DESTINATION_FOLDER = "destination-folder";
private FileFolderService fileFolderService;
private NodeService nodeService;
#Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
paramList.add(
new ParameterDefinitionImpl(DESTINATION_FOLDER,
DataTypeDefinition.NODE_REF,
true,
getParamDisplayLabel(METADATA VALUE FROM FIELD SUBJECT FROM INCOMING FILE)));}
public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
NodeRef destinationParent = (NodeRef)ruleAction.getParameterValue(DESTINATION_FOLDER);
// if the node exists
if (this.nodeService.exists(destinationParent) == true) {
try {
fileFolderService.move(incomingfile, destinationParent, null);
} catch (FileNotFoundException e) {
// Do nothing
}
if (this.nodeService.exists(destinationParent) == false) {
try {
nodeService.createNode(parentRef, assocTypeQName, assocQName, "metadata field subject");
fileFolderService.move(incomingfile, destinationParent, null);
} catch (FileNotFoundException e) {
// Do nothing
}
}
}
}
For such a simple action I'd just use a JavaScript instead of a java Action.
Install the JavaScript addon from googlecode or github (newer version)
And just write your Javascript code according the api and run it in runtime in the console to test your code.
Related
When I build project by maven, it's OK, but when deploy it by Tomkat, I have NullPointerException.
Class, where can be problem - PropertiesManager.
logline: PropertiesManager.getApplicationProperties(PropertiesManager.java:31)
public class PropertiesManager {
private static final String PROPERTY_FILE_NAME =
"resources/application.properties";
private static PropertiesManager Instance;
private Properties properties;
private PropertiesManager() {
}
public static PropertiesManager getInstance() {
if (Instance == null) {
Instance = new PropertiesManager();
}
return Instance;
}
public Properties getApplicationProperties() {
if (properties == null) {
properties = new Properties();
try (InputStream stream = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream(PROPERTY_FILE_NAME)) {
properties.load(stream);
} catch (IOException e) {
throw new ApplicationException("Failed to load property file", e);
}
}
return properties;
}
}
And logline: ApplicationLifecycleListener.contextInitialized(ApplicationLifecycleListener.java:14)
Class ApplicationLifecycleListener:
public class ApplicationLifecycleListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
Properties applicationProperties = PropertiesManager.getInstance().getApplicationProperties();
DBManager.getInstance().initialize(applicationProperties);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
DBManager.getInstance().stopDb();
}
}
What is problem can be?
Without providing the file with the exact line you see the NullPointerException (none of the files you provided have the lines shown in log), it is difficult to be sure. But one hint is that although you put your resources files to be built with Maven in the '<project>/src/main/resources' folder, when built and packing the war file, it will put your application resource files in the 'WEB-INF/classes' folder which is part of the application default classpath. Therefore, to correctly reference them using the method Thread.currentThread().getContextClassLoader().getResourceAsStream(...) you should not add the 'resources\...' prefix to the file name, since this method already look files in the default application classpath. Remove the prefix and see if it works. Please, refer to this answer for more detail.
I'm trying to receive a file uploaded to a (citrus) ftp server and verify that the content of the file uploaded is as expected.
I've managed to receive the STOR message (my code below), but I don't know how can I test that content is equals to some text (I'm working with xml, json and csv files).
Can you help me?
Thanks.
#Test
public class SampleFtpTest extends TestNGCitrusTestDesigner {
#Autowired
private FtpServer ftpServer;
#CitrusTest
public void testFileContent() {
Condition waitUntilFileIsUploaded = new Condition() {
#Override
public String getName () {
return "Check files on FTP";
}
#Override
public boolean isSatisfied (TestContext testContext){
return new File("target/ftp/user/anonymous").listFiles().length != 0;
}
#Override
public String getSuccessMessage (TestContext testContext){
return "Files found in FTP!";
}
#Override
public String getErrorMessage (TestContext testContext){
return "No file was found in FTP";
}
};
waitFor().condition(waitUntilFileIsUploaded).seconds(1200L).interval(5000L);
// simulate integration uploading a file...
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(20000L);
Runtime.getRuntime().exec("curl -T /tmp/test.txt ftp://localhost:22222 --user anonymous:secret");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
// don't care about connection related messages
receive(ftpServer);
receive(ftpServer);
receive(ftpServer);
receive(ftpServer);
receive(ftpServer);
// i'd like to assert that the uploaded files content is as expected
receive(ftpServer).header("citrus_ftp_command", FTPCmd.STOR.getCommand());
}
}
I've managed to test the file content adding a ChannelEndpoint which reads the file from the ftp working directory. Then I can test the file content doing this:
receive(fileEndpoint)
.header("file_originalFile", "#contains('/test.txt')#")
.payload(new ClassPathResource("ar/com/jidev/citrus/samples/expected/test.txt"));
For more information I uploaded the full example here
I've been working on a plugin that requires a fair amount of data being stored.
I have it being stored in a custom config file I found online that works basically the same as the default config.
The problem I'm having is that I am not sure how to actually close the file or if I even need to, as I know little about yaml configurations.
The code for the template I used is below.
I'm also curious as to advice on how I should store larger amounts of data in the future.
public class CustomConfig {
//store name of file to load/edit
private final String fileName;
//store plugin, to get file directory
private final JavaPlugin plugin;
//store actual hard disk file location
private File configFile;
//store ram file copy location
private FileConfiguration fileConfiguration;
//constructor taking a plugin and filename
public CustomConfig(JavaPlugin plugin, String fileName) {
//ensure plugin exists to get folder path
if (plugin == null)
throw new IllegalArgumentException("plugin cannot be null");
//set this classes plugin variable to the one passed to this method
this.plugin = plugin;
//get name of file to load/edit
this.fileName = fileName;
//get directory/folder of file to load/edit
File dataFolder = plugin.getDataFolder();
if (dataFolder == null)
throw new IllegalStateException();
//load config file from hard disk
this.configFile = new File(plugin.getDataFolder(), fileName);
reloadConfig();
}
public void reloadConfig() {
//load memory file from the hard copy
fileConfiguration = YamlConfiguration.loadConfiguration(configFile);
// Look for defaults in the jar
File configFile = new File(plugin.getDataFolder(), fileName);
if (configFile != null) {
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(configFile);
fileConfiguration.setDefaults(defConfig);
}
}
public FileConfiguration getConfig() {
if (fileConfiguration == null) {
this.reloadConfig();
}
return fileConfiguration;
}
public void saveConfig() {
if (fileConfiguration == null || configFile == null) {
return;
} else {
try {
getConfig().save(configFile);
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex);
}
}
}
public void saveDefaultConfig() {
if (!configFile.exists()) {
this.plugin.saveResource(fileName, false);
}
}
}
No. You do not have to close YamlConfiguration objects.
While the default config (JavaPlugin.getConfig()) is bound to the lifecycle of the plugin, custom ones are disposed when any other Java object is, i.e. when the garbage collector determines that there are no more references pointing to them in the code.
You don't need to close the config. It's not a BufferedWriter. The config keeps all of the data in the memory until the server shuts down. This means that if you change something in the config during the time your plugin is enabled, you will need to use your reloadConfig() method. The only clean up you need to do after using the FileConfiguration#set(String, Object) method is to use FileConfiguration#saveConfig() to tell Bukkit to take the current state of your config and copy it into your config file.
I try make implementation for comparing the files before they are uploaded.
If file whith name is exist in system ask about create new version or just override it.
Here is the problem, how to get file name?
I can't use receiveUpload(), because after this method file is remove from upload component ?
The problem is that once you start an upload using the Upload component, it can only be interrupted by calling the interruptUpload() method, and you cannot resume anytime later.
The interruption is permanent.
This means you cannot pause in the middle of the upload to see if you already have the file in your system. You have to upload the file all the way.
Considering this drawback, you can sill check in your system if you have the file, after the upload finishes. If you have the file, you can show a confirmation dialog in which you decide wether to keep the file or overwrite.
The following is an example in which I check in the "system" (I just keep a String list with the filenames) if the file has already been uploaded:
public class RestrictingUpload extends Upload implements Upload.SucceededListener, Upload.Receiver {
private List<String> uploadedFilenames;
private ByteArrayOutputStream latestUploadedOutputStream;
public RestrictingUpload() {
setCaption("Upload");
setButtonCaption("Upload file");
addSucceededListener(this);
setReceiver(this);
uploadedFilenames = new ArrayList<String>();
}
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
latestUploadedOutputStream = new ByteArrayOutputStream();
return latestUploadedOutputStream;
}
#Override
public void uploadSucceeded(SucceededEvent event) {
if (fileExistsInSystem(event.getFilename())) {
confirmOverwrite(event.getFilename());
} else {
uploadedFilenames.add(event.getFilename());
}
}
private void confirmOverwrite(final String filename) {
ConfirmDialog confirmDialog = new ConfirmDialog();
String message = String.format("The file %s already exists in the system. Overwrite?", filename);
confirmDialog.show(getUI(), "Overwrite?", message, "Overwrite", "Cancel", new ConfirmDialog.Listener() {
#Override
public void onClose(ConfirmDialog dialog) {
if (dialog.isConfirmed()) {
copyFileToSystem(filename);
}
}
});
}
private void copyFileToSystem(String filename) {
try {
IOUtils.write(latestUploadedOutputStream.toByteArray(), new FileOutputStream(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
}
private boolean fileExistsInSystem(String filename) {
return uploadedFilenames.contains(filename);
}
}
Note that I have used 2 external libraries:
Apache Commons IO 2.4 (http://mvnrepository.com/artifact/commons-io/commons-io/2.4) for writing to streams
ConfirmDialog from Vaadin Directory (https://vaadin.com/directory#addon/confirmdialog)
You can get the code snippet for this class from Gist: https://gist.github.com/gabrielruiu/9960772 which you can paste into your UI and test it out.
I got another JCo-related question and hopefully finding help.
With JCo you can easily build up a connection like it is explained in the example sheets which came with the JCo-library. Unfortunately, the only way building a connection is handled with a created property file. It wouldn´t be that bad, if there wasn´t any sensible data in it. But at least, the password for the SAP user stands in the file, so it is a lack of safety in this way of connection-handling. The manual of JCo says so, too :
"For this example the destination configuration is stored in a file that is called by the program. In practice you should avoid this for security reasons."
but couldn´t find a working solution after all. There are a palmful threads about this theme, like this
http://forums.sdn.sap.com/thread.jspa?messageID=7303957
but none of them are helpful. I really can´t figure out a solution and neither find one. Actually I solved the security-problem with deleting the file after building the connection, but this is not a satisfying solution. There have to be a better way getting the parameter for the connection, especially when it stands in the manual, but I have no glue how.
Anybody already worked with JCo 3.0 and knows this problem?
Yes, that's possible. You have to create your own implementation of DestinationDataProvider and register it using Environment.registerDestinationDataProvider(). However your DDP obtains the connection data and credentials is up to you. Take a look at net.sf.rcer.conn.connections.ConnectionManager, there's a working example in there.
You need to
copy the private class starting on line 66 and adapt it to your own needs (that is, fetch the connection data from wherever you want to)
perform the registration (line 204) somewhere during the startup of your application
get the connection using some string identifier that will be passed to your DestinationDataProvider.
It's a bit confusing, it was dificult to me how to figure this too.
All you need is an object of type java.util.Properties to fill the desired fields, but it's up to ou how to fill this object.
I dit it through a ValueObject, I can fill this VO from a file, database, web form...
JCOProvider jcoProvider = null;
SAPVO sap = new SAPVO(); // Value Object
Properties properties = new Properties();
if(jcoProvider == null) {
// Get SAP config from DB
try {
sap = SAPDAO.getSAPConfig(); // DAO object that gets conn data from DB
} catch (Exception ex) {
throw new ConexionSAPException(ex.getMessage());
}
// Create new conn
jcoProvider = new JCOProvider();
}
properties.setProperty(DestinationDataProvider.JCO_ASHOST, sap.getJCO_ASHOST());
properties.setProperty(DestinationDataProvider.JCO_SYSNR, sap.getJCO_SYSNR());
properties.setProperty(DestinationDataProvider.JCO_CLIENT, sap.getJCO_CLIENT());
properties.setProperty(DestinationDataProvider.JCO_USER, sap.getJCO_USER());
properties.setProperty(DestinationDataProvider.JCO_PASSWD, sap.getJCO_PASSWD());
properties.setProperty(DestinationDataProvider.JCO_LANG, sap.getJCO_LANG());
// properties.setProperty(DestinationDataProvider.JCO_TRACE, "10");
try {
jcoProvider.changePropertiesForABAP_AS(properties);
} catch (Exception e) {
throw new ConexionSAPException(e.getMessage());
}
The JCOProvider class:
import com.sap.conn.jco.ext.DestinationDataEventListener;
import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.Environment;
import es.grupotec.ejb.util.ConexionSAPException;
import java.util.Properties;
public class JCOProvider implements DestinationDataProvider {
private String SAP_SERVER = "SAPSERVER";
private DestinationDataEventListener eventListener;
private Properties ABAP_AS_properties;
public JCOProvider() {
}
#Override
public Properties getDestinationProperties(String name) {
if (name.equals(SAP_SERVER) && ABAP_AS_properties != null) {
return ABAP_AS_properties;
} else {
return null;
}
// if(ABAP_AS_properties!=null) return ABAP_AS_properties;
// else throw new RuntimeException("Destination " + name + " is not available");
}
#Override
public boolean supportsEvents() {
return true;
}
#Override
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eventListener = eventListener;
}
public void changePropertiesForABAP_AS(Properties properties) throws ConexionSAPException {
try {
if (!Environment.isDestinationDataProviderRegistered()) {
if (ABAP_AS_properties == null) {
ABAP_AS_properties = properties;
}
Environment.registerDestinationDataProvider(this);
}
if (properties == null) {
if (eventListener != null) {
eventListener.deleted(SAP_SERVER);
}
ABAP_AS_properties = null;
} else {
ABAP_AS_properties = properties;
if (eventListener != null) {
eventListener.updated(SAP_SERVER);
}
}
} catch (Exception ex) {
throw new ConexionSAPException(ex.getMessage());
}
}
}
Regards