Extend postActivity - alfresco

I want to post activities with custom datetimes.
From what I see in ActivityPostServiceImpl.java, datetimes are created there, and cannot be customized.
Here's a snippet of the code there:
try {
Date postDate = new Date();
ActivityPostEntity activityPost = new ActivityPostEntity();
activityPost.setUserId(userId);
activityPost.setSiteNetwork(tenantService.getName(siteId));
activityPost.setAppTool(appTool);
activityPost.setActivityData(activityData);
activityPost.setActivityType(activityType);
activityPost.setPostDate(postDate);
activityPost.setStatus(status.toString());
activityPost.setLastModified(postDate);
I would like to pass custom datetimes to activities, can be through the activityData object. Yet, I can't make Alfresco to load my new class (which extends ActivityPostServiceImpl) on the beans.
Any help?

The solution was to create a new CustomActivityPostService.java file, where I could extend a postActivity method to have an additional date parameter, and then modify the beans to user that service instead of the default ActivityPostService.

Related

Linq To Update One Complete Row

So I would like to update/replace one complete row with the data I have.
Instead of doing
entityA.Name = entityB.Name
I would like to say something like entityA = entityB, where entitiyB is same as entityA but has new values.
Please let me know.
Thanks..
simply doing entity1 = entity2 would change the entity1 reference and hence the context wont track the new reference ay more. Thus the changd value wont be updated.
you should be using an object mapper for that. i personally use GLUE that can be installed using command Install-Package Glue on the package manager console
There are others too like AutoMapper
if you go with glue then just make a mapping like
var mapping = new Mapping<entity1, entity2>();
mapping.AutoRelateEqualNames();
//or define a mapping using .Relate()
//then call map
mapping.Map(entity1)//this will return entity2
or if you already have an object tracked by a context class call
entity2 = mapping.Map(entity1, entity2);

Grails - Date binding in Controller

I'm trying to bind Date params in my controller. I read somewhere that it should be sufficient if I have the date in format yyyy-MM-dd HH:mm:ss.S. But this doesn't work. The other option that I read was to add _day, _month, _year, etc. suffixes to the attributes that I want to parse, but this method doesn't work either.
So it's basically a one-to-many relationship, when on the many side is the date (an Action has a VisitList<Visit> and the Visit has date).
// domain classes
class Action {
List<Visit> visitList
static hasMany = [visitList: Visit]
}
class Visit {
Action action
static belongsTo = [action: Action]
Date date
String description
}
I parse all the params to the action instance like this:
// in controller
def save(){
Action actionInstance = new Action()
action.properties = params
action.save()
}
The date is sent from view and has this format:
visitList[0].date=2012-05-15 00:00:00.0000
But the date is still null. The visit also has a description attribute and it works well. The param for this attribute is:
visitList[0].description=description
Thanks for any suggestions or advices.
Did you try saving the Visit first and then save the Action? If that doesn't work you may have to convert the date from string to Date, Date.parse() method is depreciated in grails 2.0, try this:
Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(dateString)
def action = new Action()
def visit = new Visit(date: date, description: description?:"", action: action)
visit.save()
action.visitList.add(visit)
action.save()
-HTH
Without seeing more code it's difficult to tell. You may want to try a Command Object. Where is your input coming from? A View? If so, one typically uses the and tags to control the input. If you're not using those, you may have to manually parse the date using DateFormat {hint, use the parse() method}.

Does Grails have a built-in way to bind a string to a date for a single bean property?

I know that it's possible to register a custom property editor, as demonstrated here. It is my understanding that this will cause all properties for the registered type to be bound using that custom editor.
(Perhaps that's a misunderstanding on my part? If so, enlighten me!)
However, what if I only want to register a custom editor for a single property on a given domain?
Example:
class MyCommand {
Date foo // bind this using a custom format, e.g. 'yyyy-MM-dd'
Date bar // bind this using the normal 'struct' date picker fields
}
class MyController {
def myAction = { MyCommand command ->
// params has [foo: '2011-01-01', bar: 'struct', ...]
// which get bound to command as above
}
}
Does Grails have a built-in way to do this?
I know that it's possible to register a custom property editor, as demonstrated here. It is my understanding that this will cause all properties for the registered type to be bound using that custom editor.
AFAIK, this is correct
However, what if I only want to register a custom editor for a single property on a given domain?
If you're using Grails 2.3.0 or later, you can do this like so:
class MyCommand {
#BindingFormat('yyyy-MM-dd')
Date foo // bind this using a custom format, e.g. 'yyyy-MM-dd'
Date bar // bind this using the normal 'struct' date picker fields
}
You could write getter and setters that take the format you want and return the format you want. The DateFormatter or SimpleDateFormatter classes would be useful in your get/set methods.
You can still use the neat trick for dates in grails:
<g:form>
<g:hiddenField name="myDomainInstance.bar_year" value="2011"/>
<g:hiddenField name="myDomainInstance.bar_month" value="07"/>
<g:hiddenField name="myDomainInstance.bar_day" value="01"/>
<g:textField name="myDomainInstance.bar_hour" value=""/>
<g:textField name="myDomainInstance.bar_minute" value=""/>
</g:form>
In controller:
myDomainInstance.properties = params.myDomainInstance
Will result in the desired date for bar.

Orchard: Custom Registration fields

For my Orchard project, I need some additional information from the user at registration time. (Say, First Name, Last Name, Pants Color). This information must be entered while registering and can not be deferred until later (as per client's orders).
I tried using the Profile and Extended Registration plugins to ask for those, but as far as I see, this only gives me optional fields to display in the registration form. Is there a way to present fields that are mandatory?
I also had a quick foray into overwriting the AccountController's Register method, as per this discussion, but I couldn't get it to work: The controller is in a different place, it can't be subclassed and even if I force it to, code is never executed. I presume they are using a much older version of Orchard.
So, in which direction should I go to create a mandatory field that is close to the Orchard philosophy? Should I create a new field type that rejects empty values maybe? (is that even possible)?
I wrote the ExtendedRegistration module because of that same need.
You need to create a custom part, e.g.: MyRegistrationPart.
Then you add that part to the User ContentType.
In your part just add the [Required] attribute (Data annotations) to any properties that are mandatory.
Registration will not succeed until those mandatory values have been filled out!
Hope it's clear now.
While this probably won't answer your question just wanted to point out that it is my understanding that you don't need to override/subclass the AccountController class. Instead you need to "overwrite" the Users/Account/Register route by adding your own with a higher priority. To do that you need to implement an IRouteProvider as part of our module. Since it's an IDependency it will be loaded and processed automagically at run time. Something like:
public class Routes : IRouteProvider
{
public void GetRoutes(ICollection<RouteDescriptor> routes)
{
routes.AddRange(GetRoutes());
}
public IEnumerable<RouteDescriptor> GetRoutes()
{
return new[] {
new RouteDescriptor {
// Make sure to be higher than the default
Priority = ##### PRIORITY HERE (int) ######,
Route = new Route(
"Users/Account/Register",
new RouteValueDictionary {
{"area", "#### YOUR MODULE AREA HERE ####"},
{"controller", "#### YOUR ACCOUNT CONTROLLER HERE ####"},
{"action", "#### YOUR REGISTER ACTION HERE ####"}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "#### YOUR MODULE AREA HERE ####"}
},
new MvcRouteHandler())
}
};
}
}

C# CF2.0 - System.Activator and Internal classes

I've got a data provider that contains a collection of entities. I only want to be able to create a new entity through the data provider.
I.e, to create a new record I need to use:
Entity entity = Provider.AddNew();
enity.set_Properties... etc
My issue is that if I set my entities to Internal, System.Activator cannot create an Instance of them. Each of my Data Providers uses a Base class with the generic type of the entity passed through.
So at the moment my AddNew() method contains the following:
public T AddNew()
{
T added = Activator.CreateInstance<T>();
this.Collection.Add(added);
return added;
}
It's obviously not the end of the world if I can instantiate a new entity manually outside of the Data Provider namespaces, but it seems pointless considering there's no way to ever save them, so why give the option to do so?
EDIT: Forgot to mention that all my providers, entities, etc are in the same namespace.
Don't use the Activator, which relies on a public constructor. Instead use reflection to find the parameterless constructor and then call it. Something along these lines:
Type t = typeof(MyType);
var parameterlessCtor = (from c in t.GetConstructors(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
where c.GetParameters().Length == 0
select c).FirstOrDefault;
if(parameterlessCtor != null) instance = parameterlessCtor.Invoke(null);

Resources