I have a task in which I have to present a drop down with client names while uploading a document of a particular type. The names of the client are tied to folders in a given site.
For e.g. Let say I have a site XYZ in alfresco and I have 10 folder with names Client 1 to Client 10 all on the same level, now while uploading the doc the client name field should be populated by the names of the folder present in the site.
I have created a custom java class that will fetch the folder names and place a constraint on the client name in the custom-model.xml file. I was able to show the hard-coded data as a dropdown but now I want the data to be fetched dynamically.
As I am new to alfresco I don't have enough idea how to get it done. I am trying to use Alfresco public java api and CMIS but not able to get anywhere.
Any help on this will be extremely helpful.
Here is the code.
model.xml
<!-- For client name -->
<constraint name="ev:clientNames" type="com.eisenvault.repo.dictionary.constraint.ClientNameConstraint">
<parameter name="allowedValues">
<list>
<value></value>
<!-- Will be empty -->
</list>
</parameter>
</constraint>
ClientNameConstraint.java
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ClientNameConstraint extends ListOfValuesConstraint implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
Log log = LogFactory.getLog(ClientNameConstraint.class);
private List<String> allowedValues;
protected boolean caseSensitive;
protected boolean sorted;
public ClientNameConstraint(){
caseSensitive = true;
sorted = false;
allowedValues = Collections.emptyList();
}
#Override
public List<String> getAllowedValues() {
allowedValues = Arrays.asList("Client1", "Client2", "Client3", "Client4", "Client5", "Client6");
Collections.sort(allowedValues);
super.setAllowedValues(allowedValues);
return allowedValues;
}
#Override
public void initialize() {
System.out.println("Initialized called in ClientNameConstraint....................................");
super.initialize();
checkPropertyNotNull(ALLOWED_VALUES_PARAM, allowedValues);
}
}
I would avoid using a constraint in this case. Others may disagree, but a dynamic constraint could be more trouble than it is worth. This is because you can get integrity exceptions which could be messy to deal with if your client list ever gets out of sync. Imagine if you create some documents with one version of the list, but then delete a folder. Now any operation on those documents will throw an integrity exception.
I personally would create a webscript (it could be in Javascript if you like) which reads out the folders and returns them as JSON. Then, I would create a custom share component and configure my form to use this component. The component would build the list of vales from your webscript but would not depend on a constraint.
It's "more" development than your original idea, but it's more flexible and you won't have any issues with upgrades, etc, if your client folders get out of sync with the content.
Related
In the example for the magnolia module configuration in the documentation I am not sure why the private boolean colorsEnabled;for the FooBar class is not in the YAML configuration. Where does the module configuration get the colorsEnabled property from?
maxSize: 25
welcomeMessage: Hello world
fooBar:
colors: [red, green, blue]
Also the when I programmatically retrieve the List<String> list = fooBar.getColors(); I get null for the list.
I am running Magnolia 5.7.9.
UPDATE:
My module class is done the same way as described in the documentation and the example described above.
public class XxxVersioning implements ModuleLifecycle {
private Excludes excludes;
public Excludes getExcludes() {
return excludes;
}
public void setExcludes(Excludes excludes) {
this.excludes = excludes;
}
public class Excludes {
private String red;
private String green;
public String getRed() {
return red;
}
public void setRed(String red) {
this.red = red;
}
public String getGreen() {
return green;
}
public void setGreen(String green) {
this.green = green;
}
}
I have a class that programmatically inquires if a string value is in the list. The the list appears to be null.
/**
* Find if template name for the component in the module exception list
* #param String templateName
* #return Boolean true if templateName in the module exception-list
*/
public Boolean isComponentException(String templateName) {
// get the (singleton) instance of the module
// On the module class instance call the getter methods of the module bean properties.
XxxVersioning moduleInstance = xxxVersionProvider.get();
// access the modules RenderingExcludes bean
XxxVersioning.Excludes excludes = moduleInstance.getExcludes();
String green = excludes.getGreen();
return true;
}
SOLUTION:
For bootstrapping I found the document [here][5] According to this document
All bootstrap files are only imported once!
Webapp-based bootstrap files are imported during the first run of the webapp when the Magnolia instance gets installed.
Module-based bootstrap files are imported during the installation of the module.
If you want to import bootstrap files on every start up of the Magnolia instance or of a module, you must use custom installation tasks which are executed by the Module version handler or Module start up classes.
FooBar class is not in the YAML configuration. Where does the module
configuration get the colorsEnabled property from?
First YAML/FS is checked, then from the JCR configuration (config workspace in the repo). Or if property of that name doesn't exist it would take the default value.
More on the order in which resources are checked here.
The list appears to be always null.
yes, because you override the value from yaml with the one in config workspace (or you have just one in the workspace and nothing in yaml?) and there you still write the property list in yaml format instead of using syntax appropriate for jcr (which would be contentNode called excludes with 4 properties under that node each being name/value pair representing the individual colors. Unfortunately documentation doesn't show how that differs so clearly so it's easy to make a mistake there.
Anyway, as a good practice you should choose where you will store your configuration - either in repo or in yaml. I would suggest yaml config in FS as it allows you to change the configuration from outside even if your app gets corrupted. Plus it's easier to keep that file in git or other VCS and have proper history of changes on it tracked.
Years ago on a different project, we were able to import easily large xml property files with all the custom queries we needed that could not be generated, safely wrapped in CDATA tags. Have not found the similar option in Spring Boot.
Here is what we currently have:
#Value("classpath:sql/query.sql")
private Resource queryFile;
private String query;
#PostConstruct
public void loadNewSQL() throws IOException {
InputStream is = queryFile.getInputStream();
this.query = org.apache.commons.io.IOUtils.toString(is);
}
Previously, it was config for one file and all the content were accessible by the #Value annotation. Still cannot find the modern equivalent.
I'm trying to make an uranium ingot that gives players that hold it in their inventory a wither effect. I got some tips from the minecraft forums, they told me to do to make my item give me the wither effect.
Re: 1.10.2 Item has wither « Reply #2 on: Today at 02:29:58 am » QuoteThank You Create a class that extends Item and overrides
Item#onUpdate.
In your override, check if the entityIn argument is an instance of EntityLivingBase. If it is, cast it to EntityLivingBase and call EntityLivingBase#isPotionActive to check if it has the MobEffects.WITHER effect active. If it doesn't, create a PotionEffect and call EntityLivingBase#addPotionEffect to add it.
My Question
Create and register an instance of this class instead of Item.
The last line is what im confused on.
Here is the class i made that he told me to do. Also please inform me if i didnt do something else right in this class
package item;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.MobEffects;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionEffect;
import net.minecraft.world.World;
public class UraniumIngotEffect extends Item{
#Override
public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) {
if(entityIn instanceof EntityLivingBase){
Object EntityLivingBase = ((EntityLivingBase) entityIn).isPotionActive(MobEffects.WITHER);
}else{
Object PotionEffect = new PotionEffect(MobEffects.WITHER);
}
super.onUpdate(stack, worldIn, entityIn, itemSlot, isSelected);
}
}
You need to make the item object in your mod hold the onUpdate method.
This means:
have a class that extends Item(your uranium ingot)
Register the item in the item loader
Item myurnanium = new UraniumIngot();
GameRegistry.register(myuranium);
and of course make the proper json files so the item will render properly.
I suggest you read:
http://bedrockminer.jimdo.com/modding-tutorials/basic-modding-1-8/first-item/
actually I would to retrieve two params from the #ManagedService path, but i get only null value.
The code is something like:
...
import org.atmosphere.config.service.PathParam;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Singleton;
#Singleton
#ManagedService(path = "/chat/{myId}/{destId}")
public class Chat {
#PathParam("myId")
private String mittId;
#PathParam("destId")
private String destId;
#Ready
public void onReady(AtmosphereResource r) {
logger.info("User {} want to chat with {}", mittId,destId);
}
Debugging "mittId" and "destId" are null.
There's some error on the code or something that I forget?
Actually I'm using Atmosphere-runtime 2.3.0.
Thanks to anybody that will help!
The client is correct. I resolve removing #Singleton annotation. Now while I'm debugging I can see the value of the two params.
Either you are not sharing the enough or the original back-end code or your client application is calling the chat resource incorrectly.
I tested your example and both path parameters are populated.
Please have a look at the example in the Atmosphere Github page about the the multichatroom, especially the client implementation.
I am developing a Neo4j server extension using the Neo4j Framework provided by Graphaware.
I want in my response to send the following object (simplified so that you can see the attributes) :
public class DiffResult {
private Node fileOrFolder;
private Node originalContent;
private Path path;
}
The problem is that the Node object cannot be rendered by Jackson. I have seen a NodeRepresentation class somewhare but I also don't know how to use it properly with my Spring MVC Controller.
I want my nodes to be serialized like in the Neo4j REST Api (cf documentation: http://neo4j.com/docs/stable/rest-api-nodes.html#rest-api-get-node)
I also show you the controller I am using (also simplified).
#Controller
#RequestMapping("/diff")
public class FileSpaceDiffApi {
private final GraphDatabaseService database;
#Autowired
public FileSpaceDiffApi(GraphDatabaseService database) {
this.database = database;
}
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public List<DiffResult> diff(#QueryParam("fileSpaceId") Long fileSpaceId, #QueryParam("since") Long since) {
List<DiffResult> results = new ArrayList<DiffResult>();
Transaction tx = database.beginTx();
try {
Node startNode = database.getNodeById(fileSpaceId);
DiffResult diffResult = new DiffResult();
diffResult.setFileOrFolder(startNode);
results.add(diffResult);
tx.success();
}
finally {
tx.close();
}
return results;
}
}
Ideally I'd also like to be able to render the Path in JSON.
There is (yet) no capability of easily returning nodes in the same format as Neo4j does. This is mainly because the Neo4j REST API is very generic and thus too chatty and verbose for many use-cases.
I would suggest looking at com.graphaware.api.JsonNode to which you can pass a Neo4j node and some configuration about what will be present in the generated JSON (e.g. whether to include labels, etc.)
You can use it by adding the following to your pom.xml:
<dependency>
<groupId>com.graphaware.neo4j</groupId>
<artifactId>api</artifactId>
<version>${graphaware.version}</version>
</dependency>
As for paths, there is a JsonPath class in neo4j-algorithms, that will help you achieve what you want. We will happily move to the core framework for the next release (that's where it really should be).