Using PageManager API in AEM6/CQ5 - aem

My requirement is to iterate over 8000 nodes in the JCR and create a Page object in Java for each node using PageManager API.
To start with I am using PageManager to get the title of a Page as below.
public String currentPageTitle(String pagePath) {
Page page=null;
ResourceResolver resourceResolver=null;
PageManager pageManager=null;
try {
if (pagePath != null) {
resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
pageManager = resourceResolver.adaptTo(PageManager.class);
**page = pageManager.getContainingPage(resourceResolver.getResource(pagePath));**
LOGGER.error("Page $$$$"+page);
if (page == null) {
throw new IllegalArgumentException("Page does not exist: " + pagePath);
}
}
} catch (LoginException e) {
LOGGER.error("Login Exception");
e.printStackTrace();
}
return page.getTitle();
}
Here I am getting page object as null, and it's throwing "Page does not exist: /content/geometrixx/fr.html" when i am trying to pass Geometrixx page URL to get its title.

Remove Extension(.html) and Execute.It will work Fine.
For Iteration over 80000 pages use Recursive function .
public String currentPageTitle(String pagePath) {
Page page=null;
ResourceResolver resourceResolver=null;
PageManager pageManager=null;
try {
if (pagePath != null) {
resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
pageManager = resourceResolver.adaptTo(PageManager.class);
page = pageManager.getContainingPage(resourceResolver.getResource(pagePath));
LOGGER.error("Page $$$$"+page);
if (page == null) {
throw new IllegalArgumentException("Page does not exist: " + pagePath);
}else{
buildLinkAndChildren_loop(page);
}
}
} catch (LoginException e) {
LOGGER.error("Login Exception");
e.printStackTrace();
}
return page.getTitle();
}
public void buildLinkAndChildren_loop(Page page) {
if (page != null) {
Iterator<Page> children = page.listChildren();
while (children.hasNext()) {
Page child = children.next();
buildLinkAndChildren_loop(child);
}
}
}

Related

Rollout is not being executed when triggered through a custom workflow

We have custom workflow which has a process step to trigger rollout [Standard Rollout]. The process step is completing successful but with no rollout performed.
#Component(
service = WorkflowProcess.class,
property = {
"service.description=Workflow description",
"service.vendor=Project",
"process.label=Project"
}
)
public class RolloutProcessStep implements WorkflowProcess {
private static final Logger LOG = LoggerFactory.getLogger(RolloutProcessStep.class);
#Reference
private ResourceResolverFactory resourceResolverFactory;
#Reference
private RolloutManager rolloutManager;
public void execute(WorkItem item, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException {
try (ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(
ResourceResolverFactory.SUBSERVICE, RolloutProcessStep.class.getName()))) {
triggerRollout(path, resolver);
} catch (LoginException e) {
LOG.error("Error in getting the resolver. Aborting.", e);
throw new WorkflowException("Error in getting the resolver.");
} catch (Exception e) {
LOG.error("Error in during the step. Aborting.", e);
throw new WorkflowException("Error in during the Rollout Process Step.");
}
}
private void triggerRollout(String path, ResourceResolver resolver) {
Resource source = resolver.getResource(path);
if (source == null) {
return;
}
try {
LiveRelationshipManager relationshipManager = resolver.adaptTo(LiveRelationshipManager.class);
PageManager pageManager = resolver.adaptTo(PageManager.class);
// Checks if the given source is the source of a Live Copy relationship.
if (!relationshipManager.isSource(source)) {
LOG.warn("Resource Not a valid source {}.", source);
return;
}
Page page = pageManager.getPage(source.getPath());
if (page == null) {
LOG.warn("Failed to resolve source page {}.", source);
}
final RolloutManager.RolloutParams params = new RolloutManager.RolloutParams();
params.master = page;
params.isDeep = false;
params.reset = false;
params.trigger = RolloutManager.Trigger.ROLLOUT;
LOG.info("RolloutParams {}.", params.toString());
rolloutManager.rollout(params);
} catch (WCMException e) {
LOG.error("Failed to get live relationships.", e);
}
}
}
PS: We have the blueprints configured already and rollouts performed using touch UI is working as expected.
Please let me know if I'm missing anything.
Issue was resolved by providing permission to the service user to access this Process Step.

How do I publish a check in to facebook with android SDK

The docs are terrible. I want to publish a users check in to facebook. According to the docs creating a checkin object is deprecated
https://developers.facebook.com/docs/reference/api/checkin
and instead you're supposed to add a post with location data attached. So that's what I'm trying to do. Or maybe i'm supposed to try to publish and open graph story?
Anyways here's what I have, it's basically the code to publish a post that is in their SDK sample, the post is created but there is no location data attached.
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null) {
Bundle placeBundle = new Bundle();
Bundle locationBundle = new Bundle();
Bundle postParams = new Bundle();
locationBundle.putString("latitude",String.valueOf(place.getLat()));
locationBundle.putString("longitude",String.valueOf(place.getLng()));
placeBundle.putString("id", place.getPage_id());
placeBundle.putString("name", place.getName());
placeBundle.putBundle("location", locationBundle);
postParams.putBundle("place", placeBundle);
postParams.putString("message", "test message");
Request.Callback callback = new Request.Callback() {
public void onCompleted(Response response) {
String postId = null;
try {
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
postId = graphResponse.getString("id");
}
catch (JSONException e) {
Log.i(app.TAG, "JSON error " + e.getMessage());
}
catch(Exception e){
e.printStackTrace();
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(mContext, error.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(mContext, postId, Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams, HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
else {
toast("no session to publish");
}
}
the session does have publish permissions and it WILL publish a post but all that is there is the "test message" string. The place object is from facebook's servers so it is an actual place with a page_id. When i'm debugging the post params look something like this
Bundle[{message=test message, place=Bundle[{id=171229079554355, location=Bundle[{longitude=-122.434568, latitude=37.797314}], name=The Brixton San Francisco}]}]
Session.openActiveSession(activity, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state,
Exception exception) {
if (session != null && session.isOpened()) {
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
activity, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("message", message);
postParams.putString("tags",tag);
postParams.putString("place",place_id);
Request.Callback callback = new Request.Callback() {
private String toastmessage;
public void onCompleted(Response response) {
try {
JSONObject graphResponse = response
.getGraphObject().getInnerJSONObject();
String postId = null;
postId = graphResponse.getString("id");
} catch (Exception e) {
Log.i("Test", "JSON error " + e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
isPosted(false);
Toast.makeText(
activity.getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
isPosted(true);
toastmessage = "Posted Successfully";
Toast.makeText(activity, toastmessage,
Toast.LENGTH_SHORT).show();
{
}
}
}
};
Request request = new Request(session, "me/feed",
postParams, HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}
});

wicket download output stream

I want to download csv file , i take the response content and write to it , apprently wicket write after me and the content iam getting is the page html where it should be my csv
I have seen in the example the usage of throw new AbortException();
I am using version 6.7 , do you know if my version wicket has somthing instead of it ?
or rather I am doing somthing wrong ....
can you please help me ...
add(new Link<Void>("export") {
#Override
public void onClick() {
WebResponse response = (WebResponse) getResponse();
response.setAttachmentHeader("export.csv");
response.setContentType("text/csv");
OutputStream out = getResponse().getOutputStream();
try {
c.exportData(dataSource.getListForExport(), columns, out);
} catch (Exception ex) {
System.err.println(ex);
}
}
});
public <T> void exportData(List<T> list, List<IGridColumn<IDataSource<T>, T, String>> columns, OutputStream outputStream)
throws IOException {
long startTime = System.nanoTime();
PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, Charset.forName(characterSet)));
try {
if (isExportHeadersEnabled()) {
boolean first = true;
for (IGridColumn<IDataSource<T>, T, String> col : columns) {
if (first) {
first = false;
} else {
out.print(delimiter);
System.out.println(delimiter);
}
if (col.getId().equals("checkBox")) {
continue;
}
out.print(quoteValue(col.getId()));
System.out.println(col.getId());
}
out.print("\r\n");
System.out.println("\r\n");
}
Iterator<? extends T> rowIterator = list.iterator();
while (rowIterator.hasNext()) {
T row = rowIterator.next();
boolean first = true;
for (IGridColumn<IDataSource<T>, T, String> col : columns) {
if (first) {
first = false;
} else {
out.print(delimiter);
System.out.println(delimiter);
}
if (col.getId().equals("checkBox")) {
continue;
}
Object o = (new PropertyModel<>(row, col.getId())).getObject();// ((AbstractColumn<T,
if (o != null) {
Class<?> c = o.getClass();
String s;
IConverter converter = Application.get().getConverterLocator().getConverter(c);
if (converter == null) {
s = o.toString();
} else {
s = converter.convertToString(o, Session.get().getLocale());
}
out.print(quoteValue(s));
System.out.println(quoteValue(s));
}
}
out.print("\r\n");
System.out.println("\r\n");
}
} catch (Exception ex) {
System.out.println(ex);
} finally {
System.out.println(out);
out.close();
// measure
System.out.print(System.nanoTime() - startTime);
}
}
The best way to do this is using dynamic resources. I'll suggest you to read chapter "Resource managment with Wicket" of this magnific free Wicket guide: https://code.google.com/p/wicket-guide/.
Here you have a similar example given in this guide in the section "Custom resources".
public class RSSProducerResource extends AbstractResource {
#Override
protected ResourceResponse newResourceResponse(Attributes attributes) {
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType("text/xml");
resourceResponse.setTextEncoding("utf-8");
resourceResponse.setWriteCallback(new WriteCallback()
{
#Override
public void writeData(Attributes attributes) throws IOException
{
OutputStream outputStream = attributes.getResponse().getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
SyndFeedOutput output = new SyndFeedOutput();
try {
output.output(getFeed(), writer);
} catch (FeedException e) {
throw new WicketRuntimeException("Problems writing feed to response...");
}
}
});
return resourceResponse;
}
// method getFeed()...
}
And then you need to add the link in the desired page or component:
add(new ResourceLink("rssLink", new RSSProducerResource()));

Prevent sending email and show message via plug-in

I am writing crm2011 plugin in "Email" entity with "Send" Message of Pre_operation. What i want to do is when i click "Send" button in email entity, I do the necessary checking before send. If the checking is not correct, I want to prevent and stop the sending email and show "the alert message" and stop the second plugin(this plugin send email and create the associated entity to convert "Case"). Please give me some suggestion for that plugin?
Should i use pre-Validation stage or Pre_operation state? And how can I return false to stop plugin.
public void Execute(IServiceProvider serviceProvider)
{
try
{
string message = null;
_serviceProvider = serviceProvider;
_context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
_serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
_currentUser = _context.UserId;
message = _context.MessageName.ToLower();
if (message == "send")
{
if (_context.InputParameters != null && _context.InputParameters.Contains("EmailId"))
{
object objEmailId = _context.InputParameters["EmailId"];
if (objEmailId != null)
{
_emailId = new Guid(objEmailId.ToString());
FindEmailInfo();
if (_email != null)
{
if (_email.Attributes.Contains("description") && _email.Attributes["description"] != null)//Email descritpion is not null
{
string emaildescription = StripHTML();
//Find KB Article prefix no in system config entity
serviceguideprefix = "ServiceGuidesPrefix";
QueryByAttribute query = new QueryByAttribute("ppp_systemconfig");
query.ColumnSet = new ColumnSet(true);
query.AddAttributeValue(sysconfig_name, serviceguideprefix);
EntityCollection sysconfig = _service.RetrieveMultiple(query);
if (sysconfig.Entities.Count > 0)
{
Entity e = sysconfig.Entities[0];
if (e.Attributes.Contains("ppp_value"))
{
ppp_value = e.Attributes["ppp_value"].ToString();
}
}
if (ppp_value != null && ppp_value != string.Empty)
{
//var matches = Regex.Matches(emaildescription, #"KBA-\d*-\w*").Cast<Match>().ToArray();
var matches = Regex.Matches(emaildescription, ppp_value + #"-\d*-\w*").Cast<Match>().ToArray();
//ReadKBNo(emaildescription);
foreach (Match kbnumber in matches)
{
EntityCollection kbarticlecol = FindKBArticleIds(kbnumber.ToString());
if (kbarticlecol.Entities.Count > 0)
{
Entity kbariticle = kbarticlecol.Entities[0];
if (kbariticle.Attributes.Contains("mom_internalkm"))
{
bool internalserviceguide = (bool)kbariticle.Attributes["mom_internalkm"];
if (internalserviceguide) found = true;
else found = false;
}
else found = false;
}
}
}
if (found)
{
//-----
}
}
}
}
}
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message, ex);
}
}
Well stopping the plugin is dead easy you just throw InvalidPluginException, the message you give it will be shown to the user in a alert window. You will have to do this on the pre of the send. In this case I don't think it will matter if its pre-validation or pre-operation.
Edit:
Yes, you should throw an InvalidPluginException even if no exception has happened in code. I accept this isnt what we would normally do, but its the way its meant to work. Msdn has more details: http://msdn.microsoft.com/en-us/library/gg334685.aspx
So for example the code would look like:
public void Execute(IServiceProvider serviceProvider)
{
try
{
//This is where we validate the email send
if(emailIsOkay)
{
//Do something
}
else if(emailIsNotOkay)
{
//Throw and exception that will stop the plugin and the message will be shown to the user (if its synchronous)
throw new InvalidPluginExecutionException("Hello user, your email is not correct!!");
}
}
catch (InvalidPluginExecutionException invalid)
{
//We dont to catch exception for InvalidPluginExecution, so just throw them on
throw;
}
catch (Exception ex)
{
//This exception catches if something goes wrong in the code, or some other process.
throw new InvalidPluginExecutionException(ex.Message, ex);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Crm;
using Microsoft.Xrm.Sdk;
using System.ServiceModel;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace SendEmail
{
public class Email : IPlugin
{
public void Execute(IServiceProvider serviceprovider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext));
if (!(context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity))
return;
//entity
Entity ent = (Entity)context.InputParameters["Target"];
if (ent.LogicalName != "entityName")//EntityName
throw new InvalidPluginExecutionException("Not a Service Request record! ");
//service
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService _service = serviceFactory.CreateOrganizationService(context.UserId);
string Email="";
if (ent.Contains("emailidfiled"))
Email = (string)ent["emailidfiled"];
#region email template
QueryExpression query = new QueryExpression()
{
EntityName = "template",
Criteria = new FilterExpression(LogicalOperator.And),
ColumnSet = new ColumnSet(true)
};
query.Criteria.AddCondition("title", ConditionOperator.Equal, "templateName");
EntityCollection _coll = _service.RetrieveMultiple(query);
if (_coll.Entities.Count == 0)
throw new InvalidPluginExecutionException("Unable to find the template!");
if (_coll.Entities.Count > 1)
throw new InvalidPluginExecutionException("More than one template found!");
var subjectTemplate = "";
if (_coll[0].Contains("subject"))
{
subjectTemplate = GetDataFromXml(_coll[0]["subject"].ToString(), "match");
}
var bodyTemplate = "";
if (_coll[0].Contains("body"))
{
bodyTemplate = GetDataFromXml(_coll[0]["body"].ToString(), "match");
}
#endregion
#region email prep
Entity email = new Entity("email");
Entity entTo = new Entity("activityparty");
entTo["addressused"] =Email;
Entity entFrom = new Entity("activityparty");
entFrom["partyid"] = "admin#admin.com";
email["to"] = new Entity[] { entTo };
email["from"] = new Entity[] { entFrom };
email["regardingobjectid"] = new EntityReference(ent.LogicalName, ent.Id);
email["subject"] = subjectTemplate;
email["description"] = bodyTemplate;
#endregion
#region email creation & sending
try
{
var emailid = _service.Create(email);
SendEmailRequest req = new SendEmailRequest();
req.EmailId = emailid;
req.IssueSend = true;
GetTrackingTokenEmailRequest wod_GetTrackingTokenEmailRequest = new GetTrackingTokenEmailRequest();
GetTrackingTokenEmailResponse wod_GetTrackingTokenEmailResponse = (GetTrackingTokenEmailResponse)
_service.Execute(wod_GetTrackingTokenEmailRequest);
req.TrackingToken = wod_GetTrackingTokenEmailResponse.TrackingToken;
_service.Execute(req);
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException("Email can't be saved / sent." + Environment.NewLine + "Details: " + ex.Message);
}
#endregion
}
private static string GetDataFromXml(string value, string attributeName)
{
if (string.IsNullOrEmpty(value))
{
return string.Empty;
}
XDocument document = XDocument.Parse(value);
// get the Element with the attribute name specified
XElement element = document.Descendants().Where(ele => ele.Attributes().Any(attr => attr.Name == attributeName)).FirstOrDefault();
return element == null ? string.Empty : element.Value;
}
}
}

Tag friend in wallpost with Android Facebook sdk

I'm trying to tag a friend in a wallpost using the android facebook sdk. However, what is supposed to be the tag, is blank, nothing. This is the code I've used:
Bundle params = new Bundle();
access_token = fb.getAccessToken();
try {
params.putString("format", "json");
params.putString("access_token", access_token);
String url = "https://graphs.facebook.com/me/friends";
String response = Util.openUrl(url, "GET", params);
JSONObject json = Util.parseJson(response);
JSONArray array = json.optJSONArray("data");
for(int i = 0; i < array.length(); i++) {
String tempName = array.getJSONObject(i).getString("name");
String tempID = array.getJSONObject(i).getString("id");
//Probably should have some if-tests here
if(tempName.contains(*nameOfFriend*)) {
Bundle bundle = new Bundle();
bundle.putString("message", "App tagging test");
//this is where the tagging is supposed to happen
bundle.putString("tags", *UserID*);
try {
fb.request("me/feed", bundle, "POST");
Toast.makeText(getApplicationContext(), "Tag-test", Toast.LENGTH_SHORT).show();
} catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "Couldn't find friend", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I've only granted the permission for "publish_stream", could it be that I need other permissions?
Thanks in advance for any help, guys!
Following is the working code to tag friends
Also you have to submit your review to fb for the Taggable Friends api feature of the project you created in the devlepoer facebook account.After you get the approval for your submission the following code will tag your friends.
Bundle params = new Bundle();
params.putString(Facebook.TOKEN, facebook.getAccessToken());
params.putString("method", "photos.upload");
params.putString("caption", ShareTripActivity.tripNotes); // text to post
if(ShareTripActivity.arr_facebookID.size()>0)
{
String tagFriendListId="";
for(int i=0;i<ShareTripActivity.arr_facebookID.size();i++)
{
tagFriendListId = tagFriendListId+"{'tag_uid':'"+ShareTripActivity.arr_facebookID.get(i)+"'} ,";
}
tagFriendListId=tagFriendListId.substring(0, tagFriendListId.length()-1);
params.putString("tags","["+tagFriendListId+"]");
}
AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
mAsyncRunner.request(null, params, "POST", new SampleUploadListener(), null);
//sample upload listener
public class SampleUploadListener extends BaseKeyListener implements RequestListener
{
public void onComplete(final String response, final Object state)
{
try
{
// process the response here: (executed in background thread)
Log.d("Facebook-Example", "Response: " + response.toString());
JSONObject json = Util.parseJson(response);
final String src = json.getString("src");
// then post the processed result back to the UI thread
// if we do not do this, an runtime exception will be generated
// e.g. "CalledFromWrongThreadException: Only the original
// thread that created a view hierarchy can touch its views."
}
catch (JSONException e)
{
Log.w("Facebook-Example", "JSON Error in response");
}
catch (FacebookError e)
{
Log.w("Facebook-Example", "Facebook Error: " + e.getMessage());
}
}
public void onFacebookError(FacebookError e, Object state)
{
// TODO Auto-generated method stub
}
public Bitmap getInputType(Bitmap img)
{
// TODO Auto-generated method stub
return img;
}
public int getInputType()
{
// TODO Auto-generated method stub
return 0;
}
public void onIOException(IOException e, Object state)
{
// TODO Auto-generated method stub
}
public void onFileNotFoundException(FileNotFoundException e, Object state)
{
// TODO Auto-generated method stub
}
public void onMalformedURLException(MalformedURLException e, Object state)
{
// TODO Auto-generated method stub
}
}
In this arr_facebookID is the arraylist containing the facebook_user_id of your friends whom you are going to tag.
I can’t see any value for place in your code, but that is required when tagging people in posts made via the API.
https://developers.facebook.com/docs/reference/api/user/#posts:
tags […] NOTE: You cannot specify this field without also specifying a place.