I've a problem with hibernate. I'm trying to save an object into a relational db with hibernate using orm.jar library generated by visual-paradigm tool. The problem is that it does not work but the program does not give me exceptions.
I tried to change my code but the program catches an exception and does not work.
MAIN:
CoordinatorIntrusione c = CoordinatorIntrusione.getInstance();
c.avviaRilevamento();
c.notifyProximityBySerraID(1, 4);
ArrayList<Integer> prova = new ArrayList<Integer>();
prova.add(2);
prova.add(1);
prova.add(9);
c.notifyImageBySerraID(1, prova);
System.out.println("ecco");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
c.ripristinaRilevamento(1, "1");
COORDINATORINTRUSIONE:
public class CoordinatorIntrusione {
private volatile static CoordinatorIntrusione coordinator = null;
private ThreadGroup groupBLThread;
public int avviaRilevamento() {
int code = 0;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione[] colt = esm.getColtivazioniAttive();
if(colt.length==0) {
code=-1;
return code;
}
for(int i=0; i<colt.length; i++) {
EntitySerra serra = colt[i].getEntitySerra();
int id = serra.getId();
ControllerRilevaIntrusioneBL controller = new ControllerRilevaIntrusioneBL(id, groupBLThread, "worker"+i);
controller.start();
//System.out.println("ID :"+id);
}
return code;
}
public int negaID(int id, String matricola) {
//throw new UnsupportedOperationException();
int code = -1;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione coltivazione = esm.getColtivazioneBySerraID(id);
if(coltivazione == null) return code;
String matResp = coltivazione.getEntitySerra().getResponsabile().getMatricola();
if (!matricola.equals(matResp)) return code;
ControllerRilevaIntrusioneBL controller = this.searchWorkerForID(id);
if (controller == null) return code;
code = controller.negaID();
return code;
}
public int ripristinaRilevamento(int id, String matricola) {
//throw new UnsupportedOperationException();
int code = -1;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione coltivazione = esm.getColtivazioneBySerraID(id);
if(coltivazione == null) return code;
String matResp = coltivazione.getEntitySerra().getResponsabile().getMatricola();
if (!matricola.equals(matResp)) return code;
ControllerRilevaIntrusioneBL controller = this.searchWorkerForID(id);
if (controller == null) return code;
code = controller.ripristinaRilevamento();
return code;
}
public int confermaId(int id, String matricola) {
//throw new UnsupportedOperationException();
int code = -1;
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione coltivazione = esm.getColtivazioneBySerraID(id);
if(coltivazione == null) return code;
String matResp = coltivazione.getEntitySerra().getResponsabile().getMatricola();
if (!matricola.equals(matResp)) return code;
ControllerRilevaIntrusioneBL controller = this.searchWorkerForID(id);
if (controller == null) return code;
code = controller.confermaID();
return code;
// quindi se il code è negativo le matricole non combaciano, se positivo combaciano
}
protected ControllerRilevaIntrusioneBL searchWorkerForID(int idSerra) {
ControllerRilevaIntrusioneBL[] th = new ControllerRilevaIntrusioneBL[groupBLThread.activeCount()];
groupBLThread.enumerate(th);
int i=0;
while(i<th.length) {
if(th[i].getID() == idSerra) return th[i];
i++;
}
return null;
}
private CoordinatorIntrusione() {
groupBLThread = new ThreadGroup("workerCoordinator");
}
public void notifyProximityBySerraID(int idSerra, float value) {
ControllerRilevaIntrusioneBL thread = this.searchWorkerForID(idSerra);
thread.proximityValueArrived(value);
}
public void notifyImageBySerraID(int idSerra, ArrayList<Integer> img) {
ControllerRilevaIntrusioneBL thread = this.searchWorkerForID(idSerra);
thread.imgArrived(img);
}
public static CoordinatorIntrusione getInstance() {
if (coordinator == null) {
synchronized(CoordinatorIntrusione.class){ //Serve la sincronizzazione visto che è solo lettura
if(coordinator == null){
coordinator = new CoordinatorIntrusione();
}
}
}
return coordinator;
}
}
CONTROLLERRILEVAINTRUSIONEBL:
public class ControllerRilevaIntrusioneBL extends Thread{
private int id;
private float[] valoreProssimita;
private ArrayList<Integer> img;
private static final float criticalProxValue =5;
private Semaphore proxsem;
private Semaphore camsem;
private Semaphore ripristinasem;
private Semaphore waitsem ;
protected int rilevaVolti() {
//TODO with python script
//throw new UnsupportedOperationException();
return 0;
}
public synchronized int negaID() {
//throw new UnsupportedOperationException();
int code = 0;
if (waitsem.getQueueLength() > 0) {
waitsem.release();
code = 1;
}
else code = -1;
return code;
}
public synchronized int ripristinaRilevamento() {
//throw new UnsupportedOperationException();
int code = 0;
//System.out.println(ripristinasem.getQueueLength());
if (ripristinasem.getQueueLength() > 0) {
ripristinasem.release();
code = 1;
}
else code = -1;
//System.out.println(ripristinasem.getQueueLength());
return code;
}
public synchronized int confermaID() {
//throw new UnsupportedOperationException();
int code = 0;
if (waitsem.getQueueLength() > 0) {
waitsem.release();
code = 1;
}
else code = -1;
return code;
}
public int getID() {
return id;
}
public void setID(int id) {
this.id = id;
}
#Override
public void run() {
EntitySmartFarm esm = EntitySmartFarm.getInstance();
EntityColtivazione colt = esm.getColtivazioneBySerraID(id);
EntitySerra serra = colt.getEntitySerra();
EntitySensore proximity = serra.getSensoreProssimita();
EntitySensore camera = serra.getSensoreFotografico();
//ProxySerra proxyserra = ProxySerra.getInstance();
while (true) {
//MonitoraggioProssimità
//invio messaggio alla serra
try {
proxsem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
proximity.setValore(valoreProssimita);
if(valoreProssimita[0] < criticalProxValue){
// invio messaggio camera alla serra
try {
camsem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
float[] immagine = new float[img.size()];
int index = 0;
for (Integer value: img) {
immagine[index++] = value;
}
camera.setValore(immagine);
int ret = this.rilevaVolti();
if (ret == 0 || ret == -1) {
//New ProxyNotificationSystem
if (ret == 0) {
//ProxyNotificationSystem.inviosegnalazione();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"), Locale.ITALY);
Date today = calendar.getTime();
Date ora = calendar.getTime();
int[] array = img.stream().mapToInt(i -> i).toArray();
serra.addIntrusione(today, "Selvaggina", array, ora);
} else {
try {
waitsem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
//proxynotsys.nviosegnalazione();
}
System.out.println("Thread: "+this.id+" bloccato");
try {
ripristinasem.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread: "+this.id+" Sbloccato");
}
}
}
}
public ControllerRilevaIntrusioneBL(int id, ThreadGroup group, String threadName){
super(group,threadName);
this.id = id;
valoreProssimita = new float[1];
img = new ArrayList<Integer>();
proxsem = new Semaphore(0);
camsem = new Semaphore(0);
ripristinasem = new Semaphore(0);
waitsem = new Semaphore(0);
}
public void proximityValueArrived(float value) {
valoreProssimita[0]=value;
proxsem.release();
}
public void imgArrived(ArrayList<Integer> img) {
this.img=img;
camsem.release();
}
}
ENTITYSERRA (first "addIntrusione" method catches exception and does not work, second "addIntrusione" method does not catch but does not work anyway):
public class EntitySerra {
public EntitySerra() {
}
private java.util.Set this_getSet (int key) {
if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYEMPLOYERS) {
return ORM_entityEmployers;
}
else if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYSENSORES) {
return ORM_entitySensores;
}
else if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYINTRUSIONES) {
return ORM_entityIntrusiones;
}
else if (key == vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYLETTURAS) {
return ORM_entityLetturas;
}
return null;
}
org.orm.util.ORMAdapter _ormAdapter = new org.orm.util.AbstractORMAdapter() {
public java.util.Set getSet(int key) {
return this_getSet(key);
}
};
private int id;
private java.util.Set ORM_entityEmployers = new java.util.HashSet();
private java.util.Set ORM_entitySensores = new java.util.HashSet();
private java.util.Set ORM_entityIntrusiones = new java.util.HashSet();
private java.util.Set ORM_entityLetturas = new java.util.HashSet();
private void setId(int value) {
this.id = value;
}
public int getId() {
return id;
}
public int getORMID() {
return getId();
}
public void setORM_EntityEmployers(java.util.Set value) {
this.ORM_entityEmployers = value;
}
public java.util.Set getORM_EntityEmployers() {
return ORM_entityEmployers;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntityEmployerSetCollection entityEmployers = new vista_architetturale_gestoresmartfarm.entity2.EntityEmployerSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYEMPLOYERS, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public void setORM_EntitySensores(java.util.Set value) {
this.ORM_entitySensores = value;
}
public java.util.Set getORM_EntitySensores() {
return ORM_entitySensores;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntitySensoreSetCollection entitySensores = new vista_architetturale_gestoresmartfarm.entity2.EntitySensoreSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYSENSORES, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public void setORM_EntityIntrusiones(java.util.Set value) {
this.ORM_entityIntrusiones = value;
}
public java.util.Set getORM_EntityIntrusiones() {
return ORM_entityIntrusiones;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneSetCollection entityIntrusiones = new vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYINTRUSIONES, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public void setORM_EntityLetturas(java.util.Set value) {
this.ORM_entityLetturas = value;
}
public java.util.Set getORM_EntityLetturas() {
return ORM_entityLetturas;
}
public final vista_architetturale_gestoresmartfarm.entity2.EntityLetturaSetCollection entityLetturas = new vista_architetturale_gestoresmartfarm.entity2.EntityLetturaSetCollection(this, _ormAdapter, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_ENTITYSERRA_ENTITYLETTURAS, vista_architetturale_gestoresmartfarm.entity2.ORMConstants.KEY_MUL_ONE_TO_MANY);
public String getNotifyInformationResponsabile() {
//TODO: Implement Method
String recapito = null;
Iterator<EntityEmployer> it = ORM_entityEmployers.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntityEmployer empTemp = it.next();
if(empTemp.getTipo().equals("responsabile")){
trovato = true;
recapito = empTemp.getRecapito();
}
}
return recapito;
}
public void salvaLettura() {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public void salvaLettura2() {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public void addIntrusione(java.util.Date data, String tipo, int[] img, java.util.Date ora) {
//TODO: Implement Method
EntityIntrusione intrusione = new EntityIntrusione (data, ora, tipo, img);
//DA TESTARE IMPORTANTISSIMO
ORM_entityIntrusiones.add(intrusione);
try {
//EntitySerraDAO.save(this);
EntityIntrusioneDAO.save(intrusione);
} catch (PersistentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*public synchronized void addIntrusione(java.util.Date data, String tipo, int[] img, java.util.Date ora){
//TODO: Implement Method
EntityIntrusione intrusione = new EntityIntrusione (data,ora,tipo,img);
//DA TESTARE IMPORTANTISSIMO
this.ORM_entityIntrusiones.add(intrusione);
this.entityIntrusiones.add(intrusione);
try {
Stream<EntityIntrusione> stream = this.ORM_entityIntrusiones.stream();
// salva l'ultimo elem
EntityIntrusioneDAO.save(stream.reduce((a, b) -> b).orElse(null));
} catch (PersistentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
public EntitySerra(vista_architetturale_gestoresmartfarm.entity2.EntitySerraDAO serra) {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public String[] getNotifyInformationEmployers() {
//TODO: Implement Method
throw new UnsupportedOperationException();
}
public vista_architetturale_gestoresmartfarm.entity2.EntitySensore getSensoreProssimita() {
EntitySensore sensProssimita = null;
Iterator<EntitySensore> it = ORM_entitySensores.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntitySensore sensTemp = it.next();
if(sensTemp.getTipo().equals("prossimita")){
trovato = true;
sensProssimita = sensTemp;
}
}
return sensProssimita;
}
public vista_architetturale_gestoresmartfarm.entity2.EntitySensore getSensoreFotografico() {
EntitySensore sensFotocamera = null;
Iterator<EntitySensore> it = ORM_entitySensores.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntitySensore sensTemp = it.next();
if(sensTemp.getTipo().equals("cam")){
trovato = true;
sensFotocamera = sensTemp;
}
}
return sensFotocamera;
}
public vista_architetturale_gestoresmartfarm.entity2.EntityEmployer getResponsabile() {
//TODO: Implement Method
EntityEmployer responsabile = null;
Iterator<EntityEmployer> it = ORM_entityEmployers.iterator();
boolean trovato = false;
while(trovato == false && it.hasNext()){
EntityEmployer empTemp = it.next();
if(empTemp.getTipo().equals("responsabile")){
trovato = true;
responsabile = empTemp;
}
}
return responsabile;
}
public String toString() {
return String.valueOf(getId());
}
}
ENTITYINTRUSIONEDAO:
public class EntityIntrusioneDAO {
public static boolean save(vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione entityIntrusione) throws PersistentException {
try {
vista_architetturale_gestoresmartfarm.entity2.ProgettoPSSSAgosVersionPersistentManager.instance().saveObject(entityIntrusione);
return true;
}
catch (Exception e) {
e.printStackTrace();
throw new PersistentException(e);
}
}
}
PERSISTENT MANAGER:
public class ProgettoPSSSAgosVersionPersistentManager extends PersistentManager {
private static PersistentManager _instance = null;
private static SessionType _sessionType = SessionType.THREAD_BASE;
private static int _timeToAlive = 60000;
private static JDBCConnectionSetting _connectionSetting = null;
private static Properties _extraProperties = null;
private static String _configurationFile = null;
private ProgettoPSSSAgosVersionPersistentManager() throws PersistentException {
super(_connectionSetting, _sessionType, _timeToAlive, new String[] {}, _extraProperties, _configurationFile);
setFlushMode(FlushMode.AUTO);
}
public String getProjectName() {
return PROJECT_NAME;
}
public static synchronized final PersistentManager instance() throws PersistentException {
if (_instance == null) {
_instance = new ProgettoPSSSAgosVersionPersistentManager();
}
return _instance;
}
public void disposePersistentManager() throws PersistentException {
_instance = null;
super.disposePersistentManager();
}
public static void setSessionType(SessionType sessionType) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set session type after create PersistentManager instance");
}
else {
_sessionType = sessionType;
}
}
public static void setAppBaseSessionTimeToAlive(int timeInMs) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set session time to alive after create PersistentManager instance");
}
else {
_timeToAlive = timeInMs;
}
}
public static void setJDBCConnectionSetting(JDBCConnectionSetting aConnectionSetting) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set connection setting after create PersistentManager instance");
}
else {
_connectionSetting = aConnectionSetting;
}
}
public static void setHibernateProperties(Properties aProperties) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set hibernate properties after create PersistentManager instance");
}
else {
_extraProperties = aProperties;
}
}
public static void setConfigurationFile(String aConfigurationFile) throws PersistentException {
if (_instance != null) {
throw new PersistentException("Cannot set configuration file after create PersistentManager instance");
}
else {
_configurationFile = aConfigurationFile;
}
}
public static void saveJDBCConnectionSetting() {
PersistentManager.saveJDBCConnectionSetting(PROJECT_NAME, _connectionSetting);
}
}
The exception caught is:
org.orm.PersistentException: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:598)
at org.orm.PersistentManager.saveObject(PersistentManager.java:326)
at vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneDAO.save(EntityIntrusioneDAO.java:304)
at vista_architetturale_gestoresmartfarm.entity2.EntitySerra.addIntrusione(EntitySerra.java:146)
at vista_architetturale_gestoresmartfarm.business_logic.ControllerRilevaIntrusioneBL.run(ControllerRilevaIntrusioneBL.java:139)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:89)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:115)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:69)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:625)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:279)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:260)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:305)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:655)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:647)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:642)
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:596)
... 4 more
org.orm.PersistentException: org.orm.PersistentException: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneDAO.save(EntityIntrusioneDAO.java:309)
at vista_architetturale_gestoresmartfarm.entity2.EntitySerra.addIntrusione(EntitySerra.java:146)
at vista_architetturale_gestoresmartfarm.business_logic.ControllerRilevaIntrusioneBL.run(ControllerRilevaIntrusioneBL.java:139)
Caused by: org.orm.PersistentException: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:598)
at org.orm.PersistentManager.saveObject(PersistentManager.java:326)
at vista_architetturale_gestoresmartfarm.entity2.EntityIntrusioneDAO.save(EntityIntrusioneDAO.java:304)
... 2 more
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value : vista_architetturale_gestoresmartfarm.entity2.EntityIntrusione._vista_architetturale_gestoresmartfarm.entity2.EntitySerra.ORM_EntityIntrusionesBackref
at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:89)
at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:115)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:69)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:625)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:279)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:260)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:305)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:655)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:647)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:642)
at org.orm.PersistentSession.saveOrUpdate(PersistentSession.java:596)
... 4 more
You can specify the Error Handling method when generating ORM code. May I know which option you selected?
I have one extends jFormattedTextField and in this field, I have a method to verify if it is empty, but in jTextField it works, but in jFormattedTextField no.
As I pass the fields on my frame:
RVDFormattedTextField[] obrigatoriosFTF = new RVDFormattedTextField[1];
private void setaObrigatorios() {
obrigatoriosFTF[0] = rvfCNPJ;
}
if (RVDFormattedTextField.isEmpty(obrigatoriosFTF)) {
Mensagem.aviso("Preencha os campos obrigatórios (*).", this);
} else {
Method in jFormattedTextField:
public static boolean isEmpty(RVDFormattedTextField[] campos) {
Boolean ok = false;
for (int i = 0; i < campos.length; i++) {
if (Formatacao.removerFormatacao(campos[i].getText()).trim().isEmpty()) {
ok = true;
if (campos[i].isEditable()) {
campos[i].setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255, 51, 51)));
}
} else {
campos[i].setBorder(javax.swing.BorderFactory.createEtchedBorder());
}
}
return ok;
}
Does not show errors, tried to put a sout in the method and debug however nothing happens.
Method removerFormatacao
public static String removerFormatacao(String dado) {
String retorno = "";
for (int i = 0; i < dado.length(); i++) {
if (dado.charAt(i) != '.' && dado.charAt(i) != '/' && dado.charAt(i) != '-' && dado.charAt(i) != '(' && dado.charAt(i) != ')') {
retorno = retorno + dado.charAt(i);
}
}
return (retorno);
}
Method formatarCNPJ (mask)
public static void formatarCnpj(JFormattedTextField campo) {
try {
MaskFormatter m = new MaskFormatter();
m.setPlaceholderCharacter(' ');
m.setMask("##.###.###/####-##");
campo.setCaretPosition(0);
campo.setFormatterFactory(null);
campo.setFormatterFactory(new DefaultFormatterFactory(m));
campo.setValue(null);
} catch (Exception e) {
System.err.println(e);
}
}
I tried to remove these two methods, but it still didn't work.
Well, which mask is used on the JFormattedText and how is the Formatacao.removerFormatacao implementation?
when i try to add an "object" to database and then show it to TableView it shows me UnsupportedOperationException . Everything was fine until i add this code to "public void initialize()" to make textfields as "SearchBoxes":
FilteredList <Paisjet> filteredData = new FilteredList<>(data,e -> true);
paisjaSearch.textProperty().addListener((observableValue,oldValue,newValue) ->
{
filteredData.setPredicate( paisjet ->
{
if(newValue == null || newValue.isEmpty())
{
return true;
}
String lowerCaseFilter = newValue.toLowerCase();
if(paisjet.getPaisja().toLowerCase().contains(lowerCaseFilter))
{
return true;
}
return false;
});
});
kategoriaSearch.textProperty().addListener((observableValue,oldValue,newValue) ->
{
filteredData.setPredicate( paisjet ->
{
if(newValue == null || newValue.isEmpty())
{
return true;
}
String lowerCaseFilter = newValue.toLowerCase();
if(paisjet.getKategoria().toLowerCase().contains(lowerCaseFilter))
{
return true;
}
return false;
});
});
prodhuesiSearch.textProperty().addListener((observableValue,oldValue,newValue) ->
{
filteredData.setPredicate( paisjet ->
{
if(newValue == null || newValue.isEmpty())
{
return true;
}
String lowerCaseFilter = newValue.toLowerCase();
if(paisjet.getProdhuesi().toLowerCase().contains(lowerCaseFilter))
{
return true;
}
return false;
});
});
modeliSearch.textProperty().addListener((observableValue,oldValue,newValue) ->
{
filteredData.setPredicate( paisjet ->
{
if(newValue == null || newValue.isEmpty())
{
return true;
}
String lowerCaseFilter = newValue.toLowerCase();
if(paisjet.getModeli().toLowerCase().contains(lowerCaseFilter))
{
return true;
}
return false;
});
});
SortedList <Paisjet> sortedData = new SortedList<>(filteredData);
sortedData.comparatorProperty().bind(tableView.comparatorProperty());
tableView.setItems(sortedData);
OUTPUT:
Caused by: java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at java.util.AbstractList.removeRange(AbstractList.java:571)
at java.util.AbstractList.clear(AbstractList.java:234)
at main.MainWindowController.clearTable(MainWindowController.java:315)
at main.MainWindowController.addToTableFromDatabase(MainWindowController.java:320)
at main.MainWindowController.addToDatabase(MainWindowController.java:309)
... 61 more
clearTable():
public void clearTable()
{
tableView.getItems().clear(); // line 315 at OUTPUT ERROR
}
addToTableFromDatabase():
public void addToTableFromDatabase() throws ClassNotFoundException, SQLException
{
clearTable(); //line 320 at OUTPUT ERROR
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://***.***.**.*:****/*********";
String uname="*****";
String pass="*********";
connect = (Connection) DriverManager.getConnection(url,uname,pass);
Statement statement;
String query = "SELECT * FROM paisjettable" ;
statement = connect.createStatement();
ResultSet rs = statement.executeQuery(query);
while(rs.next())
{
int id = rs.getInt("id");
String prodhuesi = rs.getString("prodhuesi");
String modeli = rs.getString("modeli");
String paisja = rs.getString("paisja");
String pjesa = rs.getString("pjesa");
String infoshtese = rs.getString("infoshtese");
double qmimi = rs.getDouble("qmimi");
double punedore = rs.getDouble("punedore");
double pagesa = rs.getDouble("pagesa");
int sasia = rs.getInt("sasia");
paisjet = new Paisjet(id,prodhuesi,modeli,paisja,pjesa,qmimi,punedore,pagesa,sasia,infoshtese);
data.add(paisjet);
tableView.setItems(data);
}
rs.close();
connect.close();
}
addToDatabase():
public void addToDatabase() throws ClassNotFoundException, SQLException
{
addToDatabaseMethod(count,prodhuesiField.getText(),modeliField.getText(),paisjaField.getText(),pjesaField.getText(),Double.parseDouble(qmimiField.getText()),Double.parseDouble(puneDoreField.getText()),Integer.parseInt(sasiaField.getText()),infoArea.getText());
count++;
prodhuesiField.clear();
modeliField.clear();
paisjaField.clear();
pjesaField.clear();
qmimiField.clear();
puneDoreField.clear();
sasiaField.clear();
infoArea.clear();
addToTableFromDatabase(); // line 309 from OUTPUT ERROR
}
You have set the table view's backing list (items) to a sorted list, which cannot be directly modified (because it is always supposed to be a sorted version of its underlying list). So table.getItems() returns the SortedList and table.getItems().clear() attempts to modify it and throws the exception.
You should modify the underlying list, which you call data in your very first code block. You haven't shown any context for the blocks of code, so it's not clear what the scope of that variable is, but you essentially need data.clear() instead of table.getItems().clear().
(Also, you do not want to call table.setItems(data) in your loop in addToTableFromDatabase, as this will remove the filtering and sorting.)
I am doing one android application, for that I used com.android.internal API's. They are Call.java, CallManger.java. For these classes I created subclass for Call.java. You can find these two classes here http://hi-android.info/src/com/android/internal/telephony/Call.java.html and http://hi-android.info/src/com/android/internal/telephony/CallManager.java.html.
Subclass of Call.java is:
public class MyCall extends Call{
1. CallManager cm = CallManager.getInstance();
2. Phone.State state;
3.
4. Phone mDefaultPhone;
5. private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
6. List<Call> ringingCall;
7.
8. #Override
9. public List<Connection> getConnections() {
10.
11.
12. state = cm.getState();
13. ringingCall = cm.getForegroundCalls();
14. System.out.println("**inside getConnections="+state);
15. System.out.println("**inside getConnections="+ringingCall);
16. if ( ringingCall == null) {
17.
18. System.out.println("**call is null***");
19. return emptyConnections;
20. }
21. else
22. {
23. System.out.println("**call is not null***");
24. return ((Call) ringingCall).getConnections();
}
}
#Override
public Phone getPhone() {
// TODO Auto-generated method stub
return null;
}
#Override
public void hangup() throws CallStateException {
// TODO Auto-generated method stub
}
#Override
public boolean isMultiparty() {
// TODO Auto-generated method stub
return false;
}
public Connection
getEarliestConnection() {
List l;
long time = Long.MAX_VALUE;
Connection c;
Connection earliest = null;
l = getConnections();
if (l == null) {
return null;
}else if ( l.size() == 0)
{
return null;
}
for (int i = 0, s = l.size() ; i < s ; i++) {
c = (Connection) l.get(i);
long t;
t = c.getCreateTime();
if (t < time) {
earliest = c;
time = t;
}
}
return earliest;
}
}
I called instance of CallManger Like this:
CallManager cm = CallManager.getInstance();
Bcoz this is a final modifier class. My another class is CallUpdate.java.
public class CallUpdate {
Call myCall = new MyCall();
Connection myConn = new MyConnection();
CallManager cm = CallManager.getInstance();
public Object getCallFailedString(){
myConn = myCall.getEarliestConnection();
System.out.println("myConn is ******"+myConn);
System.out.println("myCall is ******"+myCall);
if(myConn == null){
System.out.println("myConn is null ******");
return null;
}
else
{
Connection.DisconnectCause cause = myConn.getDisconnectCause();
System.out.println("myconn is not null ******"+cause);
}
}
I am getting myConn value is null. For this I added some piece of code in getConnection method of MyCall class to get a non-null value of myConn. i.e
state = cm.getState();
ringingCall = cm.getForegroundCalls();
System.out.println("**inside getConnections="+state);
System.out.println("**inside getConnections="+ringingCall);
if ( ringingCall == null) {
System.out.println("**call is null***");
return emptyConnections;
}
else
{
System.out.println("**call is not null***");
return ((Call) ringingCall).getConnections();
}
But it is throwing ClassCastException error on Line No:24 and on line
l = getConnections();.
And also I need at least one outgoing call to get a value of myConn. How to resolve this error?
Thx in advance.
ringingCall is a List<Call> - not a single call. You probably want something like:
if (ringingCall != null && !ringingCall.isEmpty()) {
Call call = ringingCall.get(0);
// Use call
}
... but you should also consider what you want to do if there's more than one call.
In general, if you find yourself casting that's because you think you know better than the compiler. It should always at least make you think - and in the case where you want a Call but you've got a List<Call>, the natural approach should be to use an element from the list.
It's not clear whether you really want to be subclassing Call in the first place, to be honest.
I'm doing a simple MessageRenderer.
It's specification:
Render message based on an Context (it's a map that's contains all key/value pair parameters)
Supports simple render such as: Your username is << username >>. Assume username in the context is barcelona and the result will be Your username is Barcelona.
Supported function-like object. Example: Current time is << now() >>, now(): is an object that will returns a string of current date time. And result will be: Current time is 2011-05-30
Each parameter of function can also be templated: Current time is << now( << date_format >> ) >> . This template returns a string of current date time with format is the value of key 'date_format' retrieved from the Context. Assume date_format in Context is dd/MM/yyyy and the result will be: Current time is 30/05/2011
Each parameter of function can also be templated with a different method call: Time is << now_locale ( << getLocale() >> ). Assume that getLocale() is an function object that will be return a locale is en_US and the result will be: Time is 2011/05/30 11:20:34 PM
Template can be nested. Example: Your user name is << << username >> >>. It means, Key username has value param1, Key param1 has value is barcelona so the final result will be: Your user name is Barcelona.
My classes and interfaces:
RenderContext.java
public interface RenderContext {
public String getParameter(String key);
}
MessageRenderer.java
public interface MessageRenderer {
public String render(String s, RenderContext... context);
}
MethodExpressionEvaluator.java
// Using this class to implements the method evaluation, such as now(), now_locale()
public interface MethodExpressionEvaluator {
public String evaluate(String[] methodParams, RenderContext... context);
}
AbstractMessageRenderer.java
public abstract class AbstractMessageRenderer implements MessageRenderer {
public static final String DEFAULT_NULL = "###";
public static final String PLACEHOLDER_START_TOKEN = "<<";
public static final String PLACEHOLDER_END_TOKEN = ">>";
protected int lenPlaceholderStartToken = 0;
protected int lenPlaceholderEndToken = 0;
protected String nullToken;
protected String placeholderStartToken;
protected String placeholderEndToken;
protected boolean escape = true;
public AbstractMessageRenderer() {
placeholderStartToken = PLACEHOLDER_START_TOKEN;
placeholderEndToken = PLACEHOLDER_END_TOKEN;
lenPlaceholderStartToken = placeholderStartToken.length();
lenPlaceholderEndToken = placeholderEndToken.length();
nullToken = DEFAULT_NULL;
}
public String getNullToken() {
return nullToken;
}
public void setNullToken(String defaultNull) {
this.nullToken = defaultNull;
}
public String getPlaceholderStartToken() {
return placeholderStartToken;
}
public void setPlaceholderStartToken(String placeholderStartToken) {
this.placeholderStartToken = placeholderStartToken;
lenPlaceholderStartToken = placeholderStartToken.length();
}
public String getPlaceholderEndToken() {
return placeholderEndToken;
}
public void setPlaceholderEndToken(String placeholderEndToken) {
this.placeholderEndToken = placeholderEndToken;
lenPlaceholderEndToken = placeholderEndToken.length();
}
public boolean isEscape() {
return escape;
}
public boolean getEscape() {
return escape;
}
public void setEscape(boolean escape) {
this.escape = escape;
}
public String getParam(String key, RenderContext... context) {
if(context != null)
{
for(RenderContext param:context)
{
if(param != null)
{
String value = param.getParameter(key);
if(!StringUtil.isEmpty(value))
{
return value;
}
}
}
}
return nullToken;
}
public String render(String s, RenderContext... context) {
// handle trivial cases of empty template or no placeholders
if (s == null)
{
Log4j.app.debug("Message is null in template. Cannot render null message.");
return nullToken;
}
if (context == null)
{
Log4j.app.debug("RenderContext is null. Cannot render message with null RenderContext.");
return nullToken;
}
if (s.indexOf(placeholderStartToken) < 0)
{
return s;
}
String msg = nullToken;
try
{
// private int renderTemplate(Renderable r, String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end,boolean escapes)
msg = doRender(s, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering template: " + e.getMessage(), e);
return nullToken;
}
return msg;
}
protected abstract String doRender(String s, RenderContext... context);
}
MethodExpressionRenderer.java
public class MethodExpressionRenderer extends AbstractMessageRenderer {
private boolean inSingleQuote = false;
private boolean inDoubleQuote=false;
private int placeholders;
private Stack<String> methodStack;
private String[] endTokens;
private String marker;
private List<String> methodParams;
private String prefix = "&";
public MethodExpressionRenderer() {
super();
methodStack = new Stack<String>();
marker = ",";
endTokens = new String[] { placeholderEndToken, marker, "(", ")" };
methodParams = new ArrayList<String>();
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getMarker() {
return marker;
}
public void setMarker(String marker) {
this.marker = marker;
endTokens = new String[] { placeholderEndToken, marker };
}
#Override
public void setPlaceholderEndToken(String placeholderEndToken) {
super.setPlaceholderEndToken(placeholderEndToken);
endTokens = new String[] { placeholderEndToken, marker };
}
protected String doRender(String s, RenderContext... context) {
StringBuffer sb = new StringBuffer();
try
{
renderTemplate(s, sb, nullToken, 0, endTokens, null, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering method expression message emplate: " + e.getMessage(), e);
return nullToken;
}
return sb.toString();
}
private int renderTemplate(String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end, RenderContext... context) {
int len = src.length();
while (i < len)
{
char c = src.charAt(i);
if (escape)
{
if (c=='\\')
{
i++;
char ch = src.charAt(i);
if(inSingleQuote)
{
if(ch=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(ch=='"')
{
inDoubleQuote=false;
}
}
else
{
if(ch=='\'')
{
inSingleQuote=true;
}
else if(ch=='"')
{
inDoubleQuote=true;
}
}
dst.append(ch);
i++;
continue;
}
}
if(inSingleQuote)
{
if(c=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(c=='"')
{
inDoubleQuote=false;
}
}
else
{
if(c=='\'')
{
inSingleQuote=true;
}
else if(c=='"')
{
inDoubleQuote=true;
}
}
// check for end marker
if (marks != null && !inSingleQuote && !inDoubleQuote)
{
for (int m = 0; m < marks.length; m++)
{
// If one of markers found
if (src.regionMatches(i, marks[m], 0, marks[m].length()))
{
// return marker if required
if (end != null)
{
end.append(marks[m]);
}
return i+marks[m].length();
}
}
}
// check for start of placeholder
if (src.regionMatches(i, placeholderStartToken, i, lenPlaceholderStartToken))
{
synchronized(this)
{
++placeholders;
}
i = renderPlaceholder(src, dst, nil, i, new ArrayList<String>(), context);
continue;
}
// just add plain character
if(c != '\'' && c!= '"')
{
dst.append(c);
}
i++;
}
return i;
}
private int renderPlaceholder(String src, StringBuffer dst, String nil, int i, List<String> params, RenderContext... context){
StringBuffer token = new StringBuffer(); // placeholder token
StringBuffer end = new StringBuffer(); // placeholder end marker
String value;
i = renderTemplate(src, token, nil, i+lenPlaceholderStartToken, endTokens, end);
String sToken = token.toString().trim();
String sEnd = end.toString().trim();
boolean isFunction = sEnd.equals("(");
// This is method name
if(isFunction && placeholders > methodStack.size())
{ // Method
synchronized(this)
{
methodStack.push(sToken); // put method into stack
}
}
else if(!isFunction && (methodStack.size()==0) && sEnd.equals(placeholderEndToken)) // Single template param such as <<param>>
{
value = getParam(sToken, context);
if(value != null)
{
if(value.trim().startsWith(placeholderStartToken))
{
value = render(src, context);
}
dst.append(value);
return i;
}
}
// TODO: Process method parameters to invoke
//.... ?????????
// Found end method token ')'
// Pop method out of stack to invoke
if ( (methodStack.size() >0) && (sEnd.length() == 0 || sEnd.equals(")")))
{
String method = null;
synchronized(this)
{
// Pop method out of stack to invoke
method = methodStack.pop();
--placeholders;
dst.append(invokeMethodEvaluator(method, methodParams.toArray(new String[0]), context));
methodParams.clear();
}
}
return i;
}
// Currently this method just implement to test so it just printout the method name
// and its parameter
// We can register MethodExpressionEvaluator to process
protected String invokeMethodEvaluator(String method, String[] params, RenderContext... context){
StringBuffer result = new StringBuffer();
result.append("[ ")
.append(method)
.append(" ( ");
if(params != null)
{
for(int i=0; i<params.length; i++)
{
result.append(params[i]);
if(i != params.length-1)
{
result.append(" , ");
}
}
}
result.append(" ) ")
.append(" ] ");
return result.toString();
}
}
We can easily register more method to the renderer to invoke. Each method will be an object and can be reused. But I'm in trouble how to resolve the nested method parameter. Can anyone give me an advice how we can process nested template of method parameter to invoke??? The line has TODO. Will my code in on the right way???
When you evaluate something like << count( << getTransId() >> ) >> you can either:
perform direct-evaluation as you parse, and push each function onto a stack, so that once you've evaluated getTransId() you pop the stack and use the return value (from the stack) as an argument for count(), or
you can build a parse tree to represent all the function calls that will be made, and then evaluate your parse tree after building it. (Building a tree probably doesn't buy you anything; since you're writing a template engine there is probably no high-level tree operation 'optimizations' that you could perform.)
An excellent little book I really enjoyed was Language Implementation Patterns by Parr. He walks through building simple to complex languages, and covers decisions like this in some depth. (Yes, he uses the ANTLR parser generator throughout, but your code looks like you're familiar enough with hand-generated parsers that different tools won't be a distraction for you.)
I found the bug and fixed it.
This is my new source:
// AbstractMethodExpressionRenderer.java
public class AbstractMethodExpressionRenderer extends AbstractMessageRenderer {
private boolean inSingleQuote = false;
private boolean inDoubleQuote=false;
private Stack<MethodExpressionDescriptor> functionStack;
private String[] endTokens;
private String marker;
private String prefix = "~";
public AbstractMethodExpressionRenderer() {
super();
functionStack = new Stack<MethodExpressionDescriptor>();
marker = ",";
endTokens = new String[] { placeholderEndToken, "(", ")", };
}
private class MethodExpressionDescriptor {
public List<String> params;
public String function;
public MethodExpressionDescriptor() {
params = new ArrayList<String>();
}
public MethodExpressionDescriptor(String name) {
this();
this.function = name;
}
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getMarker() {
return marker;
}
public void setMarker(String marker) {
this.marker = marker;
endTokens = new String[] { placeholderEndToken, marker };
}
#Override
public void setPlaceholderEndToken(String placeholderEndToken) {
super.setPlaceholderEndToken(placeholderEndToken);
endTokens = new String[] { placeholderEndToken, marker };
}
protected String doRender(String s, RenderContext... context) {
StringBuffer sb = new StringBuffer();
try
{
renderTemplate(s, sb, nullToken, 0, endTokens, null, context);
}
catch (Exception e)
{
Log4j.app.error("Exception in rendering method expression message emplate: " + e.getMessage(), e);
return nullToken;
}
return sb.toString();
}
private int renderTemplate(String src, StringBuffer dst, String nil, int i, String[] marks, StringBuffer end, RenderContext... context) {
int len = src.length();
while (i < len)
{
char c = src.charAt(i);
if (escape)
{
if (c=='\\')
{
i++;
char ch = src.charAt(i);
if(inSingleQuote)
{
if(ch=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(ch=='"')
{
inDoubleQuote=false;
}
}
else
{
if(ch=='\'')
{
inSingleQuote=true;
}
else if(ch=='"')
{
inDoubleQuote=true;
}
}
dst.append(ch);
i++;
continue;
}
}
if(inSingleQuote)
{
if(c=='\'')
{
inSingleQuote=false;
}
}
else if(inDoubleQuote)
{
if(c=='"')
{
inDoubleQuote=false;
}
}
else
{
if(c=='\'')
{
inSingleQuote=true;
}
else if(c=='"')
{
inDoubleQuote=true;
}
}
// check for end marker
if (marks != null && !inSingleQuote && !inDoubleQuote)
{
for (int m = 0; m < marks.length; m++)
{
// If one of markers found
if (src.regionMatches(i, marks[m], 0, marks[m].length()))
{
// return marker if required
if (end != null)
{
end.append(marks[m]);
}
return i+marks[m].length();
}
}
}
// check for start of placeholder
if (src.regionMatches(i, placeholderStartToken, 0, lenPlaceholderStartToken))
{
i = renderPlaceholder(src, dst, nil, i, new ArrayList<String>(), context);
continue;
}
// just add plain character
if(c != '\'' && c!= '"')
{
dst.append(c);
}
i++;
}
return i;
}
/**
* Render a placeholder as follows:
*
* <<key>>: Simple render, key value map
* <<function(<<param1>>, <<param2>>)>> : Function object render
*
* #param src
* #param dst
* #param nil
* #param i
* #param params
* #param context
* #return
*/
private int renderPlaceholder(String src, StringBuffer dst, String nil, int i, List<String> params, RenderContext... context){
StringBuffer token = new StringBuffer(); // placeholder token
StringBuffer end = new StringBuffer(); // placeholder end marker
String value = null;
// Simple key
i = renderTemplate(src, token, nil, i+lenPlaceholderStartToken, endTokens, end, context);
String sToken = token.toString().trim();
String sEnd = end.toString().trim();
// This is method name
if(sEnd.equals("("))
{ // Method
functionStack.add(new MethodExpressionDescriptor(sToken));
}
else // Try to resolve value
{
if(sToken.startsWith(placeholderStartToken))
{
value = render(sToken, context);
}
else if(sToken.startsWith(prefix))
{
if(functionStack.size() > 0)
{
functionStack.peek().params.add(sToken.substring(1));
}
return i;
}
else
{
value = getParam(sToken, context);
}
}
if (sEnd.length() == 0 || sEnd.equals(placeholderEndToken))
{
// No method found but found the end of placeholder token
if(functionStack.size() == 0)
{
if(value != null)
{
dst.append(value);
}
else
{
dst.append(nil);
}
}
else
{
functionStack.peek().params.add(value);
}
}
else
{
if(value != null)
{
value = value.trim();
}
if(end.substring(0, 1).equals("(") ||
end.substring(0, 1).equals(marker))
{
// right hand side is remainder of placeholder
StringBuffer tmp = new StringBuffer();
end = new StringBuffer();
i = renderTemplate(src, tmp, nil, i, endTokens, end, context);
}
if(end.substring(0, 1).equals(")"))
{
if ( functionStack.size() > 0 )
{
// Pop method out of stack to invoke
MethodExpressionDescriptor descriptor = functionStack.pop();
if(functionStack.size() > 0 )
{
functionStack.peek().params.add(invokeMethodEvaluator(descriptor.function, descriptor.params.toArray(new String[0]), context));
}
else
{
dst.append(invokeMethodEvaluator(descriptor.function, descriptor.params.toArray(new String[0]), context));
}
end = new StringBuffer();
StringBuffer tmp = new StringBuffer();
i = renderTemplate(src, tmp, nil, i, endTokens, end, context);
}
}
}
return i;
}
protected String invokeMethodEvaluator(String method, String[] params, RenderContext... context){
StringBuffer result = new StringBuffer();
result.append("[ ")
.append(method)
.append(" ( ");
if(params != null)
{
for(int i=0; i<params.length; i++)
{
result.append(params[i]);
if(i != params.length-1)
{
result.append(" , ");
}
}
}
result.append(" ) ")
.append(" ] ");
return result.toString();
}
}