Get velocity template from database in Springboot - database

I have to get velocity templates from database in Spring boot and Spring data project.I have not tried any code yet as I am new to all technologies(Velocity, Spring boot and data) and not finding anything on google. Does anybody tried here to get template from db, please suggest me some links or anything else which i can refer?
Update: I have binding classes in db (in grails) and I have to access process method from java .In db class is ,
class bindingSubject {
def log
def process = { pub,listForMail ->
def mapBinding = [:]
def fund
def perimeters = pub.sub.entities
perimeters.each(){ entity ->
if (fu == null){
if (entity instanceof S)
fu = entity.fu
if (entity instanceof Fund)
fu = fu
}
}mapBinding.entity = fu.name return mapBinding
}
}
and java code written to
-> Load script
mapScriptClass = new HashMap<String, Object>();
if (script != null) {
if (mapScriptClass.get(name) == null) {
GroovyCodeSource groovySource = new GroovyCodeSource(script,name,"");
GroovyClassLoader classLoader = new GroovyClassLoader(this.getClass().getClassLoader());
// Load string as Groovy script class.
Class scriptClass = classLoader.parseClass(groovySource);
try {
Object classInstance = scriptClass.newInstance();
ApplicationContext ctx = (ApplicationContext)ServletContextHolder
.getServletContext().getAttribute(ApplicationAttributes.APPLICATION_CONTEXT);
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(classInstance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
mapScriptClass.put(name, classInstance);
return classInstance;
To call process method from db(in grails this works , how to do it in java?)
Object scriptClass = loadScriptService.getScriptClass("scriptBindingSubject"+templateMail.getId(),
templateMail.getScriptBindingSubject());
if (scriptClass != null) {
try{
bindingSubject = scriptClass.process(pub,subMail);
}
now i am not sure how to call process method from java(to db) to bind properties
Thanks.

As you write, the templates are stored in the database.
So you need to read them (using JDBC or JPA) and depending on how they are stored, you will get a String, char[] or byte[].
You can convert all of them into a java.io.Reader like
CharArrayReader, StringReader,
how this can be done for a byte[] you can see in this tutorial
SimpleTemplateEngine has a method
createTemplate(Reader reader)
that finally creates the template for the reader.
Hope that helps.

Related

It is necessary to perform the planned action through the apex scheduler

i have this code:
public static String currencyConverter() {
allCurrency test = new allCurrency();
HttpRequest request = new HttpRequest();
HttpResponse response = new HttpResponse();
Http http = new Http();
request.setEndpoint(endPoint);
request.setMethod('GET');
response = http.send(request);
String JSONresponse = response.getBody();
currencyJSON currencyJSON = (currencyJSON)JSON.deserialize(JSONresponse, currencyJSON.class);
test.USD = currencyJSON.rates.USD;
test.CAD = currencyJSON.rates.CAD;
test.EUR = currencyJSON.rates.EUR;
test.GBP = currencyJSON.rates.GBP;
Log__c logObject = new Log__c();
logObject.Status_Code__c = String.valueOf(response.getStatusCode());
logObject.Response_Body__c = response.getBody();
insert logObject;
if (response.getStatusCode() == 200) {
Exchange_Rate__c ExchangeRateObject = new Exchange_Rate__c();
ExchangeRateObject.CAD__c = currencyJSON.rates.CAD;
ExchangeRateObject.EUR__c = currencyJSON.rates.EUR;
ExchangeRateObject.GBP__c = currencyJSON.rates.GBP;
ExchangeRateObject.USD__c = currencyJSON.rates.USD;
ExchangeRateObject.Log__c = logObject.id;
insert ExchangeRateObject;
}
return JSON.serialize(test);
}
Here I am getting different currencies and then calling them in LWC and also I create two objects with values.
I want these objects to be created every day at 12PM.
Tell me how to implement this through the apex scheduler.
You need a class that implements Schedulable. Can be this class, just add that to the header and add execute method. Or can be separate class, doesn't matter much.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm
Something like
public with sharing MyClass implements Schedulable{
public static String currencyConverter() { ... your method here }
public void execute(SchedulableContext sc) {
currencyConverter();
}
}
Once your class saves OK you should be able to schedule it from UI (Setup -> Apex Classes -> button) or with System.schedule 1-liner from Developer Console for example.
Alternative would be to have a scheduled Flow - but that's bit more work with making your Apex callable from Flow.
P.S. Don't name your variables test. Eventually some time later you may need "real" stuff like Test.isRunningTest() and that will be "fun". It's like writing
Integer Account = 5; // happy debugging suckers

How to reload list resource bundle in ADF 12c

I fail to reload my resource bundle class to reflect the changed translations (made my end-user) on page. Although getContent method executes and all translations as key/value fetched from database and object[][] returned from getContent method successfully. this happens after each time I clear the cache and refresh the jsf page through actionListener.
ResourceBundle.clearCache();
Also I tried to use the below and got the same result.
ResourceBundle.clearCache(Thread.currentThread().GetContextClassLoader());
Why WLS always see the old one? Am I miss something?
versions: 12.2.1.1.0 and 12.2.1.3.0
The end user - after making the translations and contributing to the internationalization of the project, the translations are saved to the database,
The process to inforce these operations are done through the following steps:
Create a HashMap and load all the resource key/vale pairs in the map
from the database:
while (rs.next()) {
bundle.put(rs.getString(1), rs.getString(2));
}
Refresh the Bundle of your application
SoftCache cache =
(SoftCache)getFieldFromClass(ResourceBundle.class,
"cacheList");
synchronized (cache) {
ArrayList myBundles = new ArrayList();
Iterator keyIter = cache.keySet().iterator();
while (keyIter.hasNext()) {
Object key = keyIter.next();
String name =
(String)getFieldFromObject(key, "searchName");
if (name.startsWith(bundleName)) {
myBundles.add(key);
sLog.info("Resourcebundle " + name +
" will be refreshed.");
}
}
cache.keySet().removeAll(myBundles);
Getthe a String from ResourceBoundle of your application:
for (String resourcebundle : bundleNames) {
String bundleName =
resourcebundle + (bundlePostfix == null ? "" : bundlePostfix);
try {
bundle = ResourceBundle.getBundle(bundleName, locale, getCurrentLoader(bundleName));
} catch (MissingResourceException e) {
// bundle with this name not found;
}
if (bundle == null)
continue;
try {
message = bundle.getString(key);
if (message != null)
break;
} catch (Exception e) {
}
}

TryUpdateModel showing the curect data but db is not saving it

I'm trying to save a single item into a SQL Server tableusing TryUpdateModel. When debugging, I can see the value that needs to be updated, but the db.SaveChanges() call is not saving it.
My code:
[HttpGet]
public PartialViewResult _SubmitRev(int? id)
{
return PartialView();
}
[HttpPost]
public PartialViewResult _SubmitRev(int? id, WriterSubjectReviewVm model)
{
var loggedInUserId = User.Identity.GetUserId();
var member = db.Members.SingleOrDefault(m => m.ApplicationUserId == loggedInUserId);
var MySubjectDetails = (from c in db.subjects.Where(s => s.SubjectId == id) select c).AsNoTracking().Single();
model.rev.SubjectId = (int)id;
model.sub.SubjectId = MySubjectDetails.SubjectId;
var bad = MySubjectDetails.Bad;
model.sub.Bad = bad;
if (model.rev.GBU == "Bad")
{
int iBadRating = Convert.ToInt32(bad);
iBadRating++;
model.sub.Bad = iBadRating;
}
if (ModelState.IsValid)
{
// TryUpdateModel(model.sub, "Subject");
TryUpdateModel(model.sub);
db.SaveChanges();
return PartialView();
}
return PartialView(model);
}
Looking at your code, I would say that you aren't re-attaching your model back to the context. Let's break it down:
First, your model is coming into the method as a new object:
public PartialViewResult _SubmitRev(int? id, WriterSubjectReviewVm model)
Then you modify it a bit using data from your DB:
var MySubjectDetails = (from c in db.subjects.Where(s => s.SubjectId == id) select c).AsNoTracking().Single();
model.rev.SubjectId = (int)id;
model.sub.SubjectId = MySubjectDetails.SubjectId;
Important to note that you are pulling MySubjectDetails using .AsNoTracking(), which pulls it disconnected from the context, so this won't automatically save at all unless you re-attach it.
You then assign that disconnected entity to your model:
var bad = MySubjectDetails.Bad;
model.sub.Bad = bad;
Then you modify some more properties, then you check if the model is valid and try and save it:
if (ModelState.IsValid)
{
// TryUpdateModel(model.sub, "Subject");
TryUpdateModel(model.sub);
db.SaveChanges();
return PartialView();
}
At no point have you reconnected your model object back to the context (db), so when you call .SaveChanges(), what are you saving?
The Solution
At some stage you need to map the properties as posted to your Action (in the form of the WriterSubjectReviewVm view model) back onto a data model. Otherwise if that view model is actually a data model (and exists on your DB context in a collection somewhere) then you need to reattach it:
db.WriterSubjectReviews.Attach(model)
Or something similar - then when you call SaveChanges() it will actually save.

EpiServer - get absolute friendly url for given culture for page

I've a following setup in my Manage Websites panel
General Url is set to alloy.com
alloy.no is set for no culture
alloy.se is set for sv culture
alloy.com is set for en culture
In my code, i want to get the friendly external url for given language for given page.
So for Search page I want to get absolute friendly url in all languages.
I use following code to get friendly url for page (found on Anders G. Nordby blog):
var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>();
var pageAddress = urlResolver.GetUrl(reference, language);
var builder = new UrlBuilder(pageAddress);
Global.UrlRewriteProvider.ConvertToExternal(builder, null, Encoding.UTF8);
var friendlyUrl = builder.Uri.IsAbsoluteUri
? builder.ToString()
: UriSupport.AbsoluteUrlBySettings(builder.ToString());
return friendlyUrl;
It is simple if I will use the alloy.com webpage and in my custom code generate friendly url.
no - alloy.no/søk
se - alloy.se/sök
en - alloy.com/search
But when I use alloy.no to enter edit mode and I will try to generate address for no i get alloy.com/søk when it should be alloy.no/søk.
I found that if I use alloy.no to go to Edit Mode, code :
urlResolver.GetUrl(reference, language)
returns only /søk and code
UriSupport.AbsoluteUrlBySettings(builder.ToString())
add the General URL (alloy.com) instead of alloy.no.
How can I improve this code to take correct host name for page in different culture?
The GetUrl method of the UrlResolver will return a URL to a page that is relative or absolute depending on the current request context. A URL will be relative if the page is located in the current site and absolute if in another site or if the call is made outside a request.
If you are using EPiServer.CMS.Core version 8.0 or later there is also support for identifying one site as the primary site. This update also made it possible to explicitly request that the URL should be to the primary site by setting the ForceCanonical flag on the VirtualPathArguments parameter. If not the flag is not set, it will prefer the current site URL over the primary (given the requested content is located on the current site).
So, with this in mind, you can assume that the returned URL, if not absolute, will be relative to the currently requested site and safely combine it with the currently requested URL such as:
private static string ExternalUrl(this ContentReference contentLink, CultureInfo language)
{
var urlString = UrlResolver.Current.GetUrl(contentLink, language.Name, new VirtualPathArguments { ForceCanonical = true });
if (string.IsNullOrEmpty(urlString) || HttpContext.Current == null) return urlString;
var uri = new Uri(urlString, UriKind.RelativeOrAbsolute);
if (uri.IsAbsoluteUri) return urlString;
return new Uri(HttpContext.Current.Request.Url, uri).ToString();
}
In most cases I would probably prefer not to use HttpContext.Current directly and instead pass in the current request URL. But in this case I have opted to use it directly to keep the example more contained.
We have a support case regarding this. We want the url resolver to always return an absolute url when requesting the canonical url. This is our current solution:
public static string ExternalUrl(this PageData p, bool absoluteUrl, string languageBranch)
{
var result = ServiceLocator.Current.GetInstance<UrlResolver>().GetUrl(
p.ContentLink,
languageBranch,
new VirtualPathArguments
{
ContextMode = ContextMode.Default,
ForceCanonical = absoluteUrl
});
// HACK: Temprorary fix until GetUrl and ForceCanonical works as expected,
// i.e returning an absolute URL even if there is a HTTP context that matches the page's
// site definition and host.
if (absoluteUrl)
{
Uri relativeUri;
if (Uri.TryCreate(result, UriKind.RelativeOrAbsolute, out relativeUri))
{
if (!relativeUri.IsAbsoluteUri)
{
var siteDefinitionResolver = ServiceLocator.Current.GetInstance<SiteDefinitionResolver>();
var siteDefinition = siteDefinitionResolver.GetDefinitionForContent(p.ContentLink, true, true);
var hosts = siteDefinition.GetHosts(p.Language, true);
var host = hosts.FirstOrDefault(h => h.Type == HostDefinitionType.Primary) ?? hosts.FirstOrDefault(h => h.Type == HostDefinitionType.Undefined);
var basetUri = siteDefinition.SiteUrl;
if (host != null)
{
// Try to create a new base URI from the host with the site's URI scheme. Name should be a valid
// authority, i.e. have a port number if it differs from the URI scheme's default port number.
Uri.TryCreate(siteDefinition.SiteUrl.Scheme + "://" + host.Name, UriKind.Absolute, out basetUri);
}
var absoluteUri = new Uri(basetUri, relativeUri);
return absoluteUri.AbsoluteUri;
}
}
}
return result;
}
I also ran into this issue when writing a scheduled job running on a multilanguage, multihostname site. In order to get an absolute url with the right hostname in a HttpContext-less situation I had to combine Henrik's code with Dejan's code from here: https://www.dcaric.com/blog/episerver-how-to-get-external-page-url.
This is what I came up with:
public static string ExternalUrl(this ContentReference contentLink, CultureInfo language)
{
var urlString = UrlResolver.Current.GetUrl(contentLink, language.Name, new VirtualPathArguments { ForceCanonical = true });
var uri = new Uri(urlString, UriKind.RelativeOrAbsolute);
if (uri.IsAbsoluteUri) return urlString;
string externalUrl = HttpContext.Current == null
? UriSupport.AbsoluteUrlBySettings(urlString)
: HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + urlString;
return externalUrl;
}
I've manage to write something base on the Johan & Henry answers:
public static string GetExternalAbsoluteFriendlyUrl(
this ContentReference reference,
string language)
{
var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>();
var friendlyUrl = urlResolver.GetUrl(reference, language);
if (string.IsNullOrEmpty(friendlyUrl))
return friendlyUrl;
var uri = new Uri(friendlyUrl, UriKind.RelativeOrAbsolute);
if (uri.IsAbsoluteUri)
return friendlyUrl;
if (HttpContext.Current != null)
return new Uri(HttpContext.Current.Request.Url, uri).ToString();
var siteDefinitionResolver =
ServiceLocator.Current.GetInstance<SiteDefinitionResolver>();
var siteDefinition =
siteDefinitionResolver.GetDefinitionForContent(reference, true, true);
return new Uri(siteDefinition.SiteUrl, friendlyUrl).ToString();
}

How to know the order of update with Domain context SubmitChanges?

Suppose I have 3 entities generated from EF, say tab1, tab2 and tab3. In SL app, I call SubmitChanges to save data to DB, all changes will be process by WCF and EF automatically.
Question is: how can I know the order of Update operation in Database?
I need to know this because I have triggers on those tables and need to know the order of the updating.
One thing you can do is to override the PeristChangeSet() in your DomainService and manually control the order of saves. Just do nothing in your regular update/insert statements. Here's some pseudocode for a saving a document exmmple to explain my answer:
[Insert]
public void InsertDocument(MyDocument objDocument) { }
[Update]
public void UpdateDocument(MyDocument objDocument) { }
protected override bool PersistChangeSet()
{
try {
// have to save document first to get its id....
MyDocument objDocumentBeingSaved = null;
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is MyDocument)) {
var changedEntity = (MyDocument)CSE.Entity;
objDocumentBeingSaved = documentRepository.SaveDocument(changedEntity);
break; // only one doc
}
if (objDocumentBeingSaved == null)
throw new NullReferenceException("CreateDocumentDomainService.PersistChangeSet(): Error saving document information. Document is null in entity set.");
// save document assignments after saving document object
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is DocumentAssignment)) {
var changedEntity = (DocumentAssignment)CSE.Entity;
changedEntity.DocumentId = objDocumentBeingSaved.Id;
changedEntity.Id = documentRepository.SaveDocumentAssignment(objDocumentBeingSaved, changedEntity);
}
// save line items after saving document assignments
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is LineItem)) {
var changedEntity = (LineItem)CSE.Entity;
changedEntity.DocumentId = objDocumentBeingSaved.Id;
changedEntity.Id = documentRepository.SaveLineItem(objDocumentBeingSaved, changedEntity);
}
documentRepository.GenerateDocumentNumber(objDocumentBeingSaved.Id);
}
catch {
// ....
throw;
}
return false;
}

Resources