Xtext project JDT Independence - xtext

I created editor with Xtext 2.9.1 and now I want to make it independent of JDT. I followed this guide https://eclipse.org/Xtext/documentation/307_special_languages.html
but it does not seem to work. This is my ErrmsgUiModule.xtend
#FinalFieldsConstructor
class ErrmsgUiModule extends AbstractErrmsgUiModule {
override configure(Binder binder) {
super.configure(binder);
binder.bind(DefaultHighlightingConfiguration).to(ErrMsgHighlightingConfiguration);
binder.bind(DefaultSemanticHighlightingCalculator).to(ErrorSemanticHighlightingCalculator);
}
override bindIResourceForEditorInputFactory() {
return ResourceForIEditorInputFactory
}
override bindIResourceSetProvider() {
return SimpleResourceSetProvider
}
override provideIAllContainersState() {
return Access.getWorkspaceProjectsState()
}
}
I checked every overwritten method with debugger and all 3 methods are called. I did not created my own project wizard so this should be enough.
But still after plugin installating the Java project wizard becomes available...
/Edit:
To provide more information, this is project's mwe2 file
module com.xxx.lang.errmsg.GenerateErrmsg
import org.eclipse.xtext.xtext.generator.*
import org.eclipse.xtext.xtext.generator.model.project.*
import org.eclipse.xtext.ui.generator.*
var rootPath = ".."
Workflow {
component = XtextGenerator {
configuration = {
project = StandardProjectConfig {
baseName = "com.xxx.lang.errmsg"
rootPath = rootPath
runtimeTest = {
enabled = true
}
eclipsePlugin = {
enabled = true
}
eclipsePluginTest = {
enabled = true
}
createEclipseMetaData = true
}
code = {
encoding = "windows-1250"
fileHeader = "/*\n * generated by Xtext \${version}\n */"
}
}
language = StandardLanguage {
name = "com.xxx.lang.errmsg.Errmsg"
fileExtensions = "msg"
fragment = formatting.Formatter2Fragment2 auto-inject {}
serializer = {
generateStub = false
}
validator = {
// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
}
}
}
}
and this is list of Dependencies from plugin.xml for various projects:
project com.xxx.lang.errmsg
org.eclipse.xtext,
org.eclipse.xtext.xbase,
org.eclipse.equinox.common;bundle-version="3.5.0",
org.eclipse.emf.ecore,
org.eclipse.xtext.xbase.lib,
org.antlr.runtime,
org.eclipse.xtext.util,
org.eclipse.xtend.lib,
org.eclipse.emf.common,
org.objectweb.asm;bundle-version="[5.0.1,6.0.0)";resolution:=optional,
org.eclipse.xtext.ui
project com.xxx.lang.errmsg.ui
com.xxx.lang.errmsg,
com.xxx.lang.errmsg.ide,
org.eclipse.xtext.ui,
org.eclipse.xtext.ui.shared,
org.eclipse.xtext.ui.codetemplates.ui,
org.eclipse.ui.editors;bundle-version="3.5.0",
org.eclipse.ui.ide;bundle-version="3.5.0",
org.eclipse.ui,
org.eclipse.compare,
org.eclipse.xtext.builder,
org.eclipse.xtend.lib;resolution:=optional,
org.eclipse.xtext.xbase.lib,
org.eclipse.xtext.xbase.ui
/Edit2: According to this topic https://bugs.eclipse.org/bugs/show_bug.cgi?id=336217, I also tried to disable all org.eclipse.jdt* plugins in run configuration. This is what i get http://pastebin.com/Wi0gzceM

You have to remove the dependencies on org.eclipse.xtext.xbase and org.eclipse.xtext.xbase.ui from your runtime and UI project.
Make sure if you open the Plug-in Dependencies in the Package Explorer that you do not see org.eclipse.jdt.core in the list. If so, there is another plug-in having a (transitive) dependency. Find out which and remove.

Related

How to replace Servlet Filters already defined (replacing legacy doWithWebDescriptor with doWithSpring)

I'm trying to upgrade a Grails plugin from version 2.3.4 to 4.0.11. It uses a syntax that is no longer supported to replace filters with names sitemesh and urlMapping with its own filters.
The code below uses a DSL for xml. It replaces xml nodes in the final generated web.xml.
def doWithWebDescriptor = { xml ->
def pageFilter = xml.filter.find { it.'filter-name'.text() == 'sitemesh' }
def urlMappingFilter = xml.filter.find { it.'filter-name'.text() == 'urlMapping' }
def grailsVersion = GrailsUtil.grailsVersion
// Grails 1.3.x & Grails 2.0.x
def pageFilterClass = "org.zkoss.zk.grails.web.ZKGrailsPageFilter"
def urlMappingFilterClass = "org.zkoss.zk.grails.web.ZULUrlMappingsFilter"
if(grailsVersion.startsWith("2")) {
pageFilter.'filter-class'.replaceNode {
'filter-class'(pageFilterClass)
}
urlMappingFilter.'filter-class'.replaceNode {
'filter-class'(urlMappingFilterClass)
}
//
// Require a legacy config for servlet version
//
if(application.metadata.getServletVersion() >= '3.0') {
pageFilter.'filter-class' + {
'async-supported'('true')
}
urlMappingFilter.'filter-class' + {
'async-supported'('true')
}
}
} else {
pageFilter.'filter-class'.replaceBody(pageFilterClass)
urlMappingFilter.'filter-class'.replaceBody(urlMappingFilterClass)
}
}
What I tried so far
The code below uses Grails plugin configuration to register filters with spring's FilterRegistrationBean. I'm following Grails official documentation.
Closure doWithSpring() { { ->
boolean supportsAsync = this.grailsApplication.metadata.getServletVersion() >= "3.0"
pageFilter(FilterRegistrationBean) {
name = "sitemesh"
filter = bean(org.zkoss.zk.grails.web.ZKGrailsPageFilter)
urlPatterns = ["/*"]
order = Ordered.HIGHEST_PRECEDENCE
asyncSupported = supportsAsync
}
urlMappingFilter(FilterRegistrationBean) {
name = "urlMapping"
filter = bean(org.zkoss.zk.grails.web.ZULUrlMappingsFilter)
urlPatterns = ["/*"]
order = Ordered.HIGHEST_PRECEDENCE
asyncSupported = supportsAsync
}
}}
How can I replicate the legacy code with RegistrationBeans?
Also, I don't know if any of these filters got deprecated by Grails. I would like to know if there are any other replacements, if possible.
Here's the project in case anyone wants more context.
Debugging the older version of the plugin I came up with the following:
pageFilter(FilterRegistrationBean) {
name = "sitemesh"
filter = bean(ZKGrailsPageFilter)
urlPatterns = ["/*"]
order = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER + 50
asyncSupported = supportsAsync
dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR)
}
urlMappingFilter(FilterRegistrationBean) {
name = "urlMapping"
filter = bean(ZULUrlMappingsFilter)
urlPatterns = ["/*"]
order = OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER + 60
asyncSupported = supportsAsync
dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD)
}
Added the dispatcherTypes and changed the order assuming these would be the last filters where the 'pageFilter' should be placed before the 'urlMappingFilter' in the filter chain.

Where's located the declaration of messageSource in Grails?

Background
We have some legacy internationalization for field labels that are stored in the database, so I tried to make a "merged" messageSource. If the code exists in database, return, if not, use PluginAwareResourceBundleMessageSource to look in the i18n.
Problem
For some reason the cachedMergedPluginProperties is caching the wrong file for the locale. For example, if I search for en_US, I receive pt_BR messages (the key of the Map is en_US, but the properties are pt_BR).
I declared my messageSource as follows:
messageSource(DatabaseMessageSource) {
messageBundleMessageSource = { org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSource m ->
basenames = "WEB-INF/grails-app/i18n/messages"
}
}
The inner bean is beacause of Grails won't let me have two beans of type MessageSource.
Am I declaring PluginAwareResourceBundleMessageSource different from the default of Grails? In which file of Grails I can see this bean declaration?
I found the declaration inside I18nGrailsPlugin, and it's a bit more detailed then mine:
String baseDir = "grails-app/i18n"
String version = GrailsUtil.getGrailsVersion()
String watchedResources = "file:./${baseDir}/**/*.properties".toString()
...
Set baseNames = []
def messageResources
if (application.warDeployed) {
messageResources = parentCtx?.getResources("**/WEB-INF/${baseDir}/**/*.properties")?.toList()
}
else {
messageResources = plugin.watchedResources
}
if (messageResources) {
for (resource in messageResources) {
// Extract the file path of the file's parent directory
// that comes after "grails-app/i18n".
String path
if (resource instanceof ContextResource) {
path = StringUtils.substringAfter(resource.pathWithinContext, baseDir)
}
else {
path = StringUtils.substringAfter(resource.path, baseDir)
}
// look for an underscore in the file name (not the full path)
String fileName = resource.filename
int firstUnderscore = fileName.indexOf('_')
if (firstUnderscore > 0) {
// grab everyting up to but not including
// the first underscore in the file name
int numberOfCharsToRemove = fileName.length() - firstUnderscore
int lastCharacterToRetain = -1 * (numberOfCharsToRemove + 1)
path = path[0..lastCharacterToRetain]
}
else {
// Lop off the extension - the "basenames" property in the
// message source cannot have entries with an extension.
path -= ".properties"
}
baseNames << "WEB-INF/" + baseDir + path
}
}
LOG.debug "Creating messageSource with basenames: $baseNames"
messageSource(PluginAwareResourceBundleMessageSource) {
basenames = baseNames.toArray()
fallbackToSystemLocale = false
pluginManager = manager
if (Environment.current.isReloadEnabled() || GrailsConfigUtils.isConfigTrue(application, GroovyPagesTemplateEngine.CONFIG_PROPERTY_GSP_ENABLE_RELOAD)) {
def cacheSecondsSetting = application?.flatConfig?.get('grails.i18n.cache.seconds')
if (cacheSecondsSetting != null) {
cacheSeconds = cacheSecondsSetting as Integer
} else {
cacheSeconds = 5
}
}
}
Since Grails don't let you have two beans of type MessageSource I had to copy this code and adapt to mine "merged" messageSource.

Grails JCaptcha testing mode

Anyone used the JCaptcha grails plugin know if this has a test mode (for use with automated testing, GEB/Selenium), or do I manually have to add a test parameter to my config file and check this in all controllers where the captcha is checked?
Did not find a test mode, but worked around it by defining a test mode variable in the grails config file.
def captchaOK = false
try {
captchaOK = jcaptchaService.validateResponse("captchaImage", session.id, params.captchaText)
}
}
catch(CaptchaServiceException cse) {
captchaOK = false;
}
Was replaced with:
def captchaOK = false
try {
if(grailsApplication.config.capatchaTestMode == true) {
captchaOK = true;
}
else {
captchaOK = jcaptchaService.validateResponse("captchaImage", session.id, params.captchaText)
}
}
catch(CaptchaServiceException cse) {
captchaOK = false;
}

Grails JMS Plugin to WebLogic JMS Server

Has anyone configured Grails 2.x JMS Plugin to send/receive messages to a remote WebLogic JMS Server? I've tried resources.groovy configurations like this with no luck:
jmsConnectionFactory(InitialContext, [
"INITIAL_CONTEXT_FACTORY": "weblogic.jndi.WLInitialContextFactory",
"PROVIDER_URL": "t3://remote-host:7001",
"SECURITY_PRINCIPAL": "weblogic",
"SECURITY_CREDENTIALS": "weblogic"])
Not much resources with complete answers are on net about sending/receiving JMS in Grails with remote Weblogic server, so I figured out 2-3 years ago a working solution, without need of any plugins.
Make sure that at least Weblogic wlthint3client.jar is in lib directory.
Setting up JMS listener:
in conf/spring/resources.groovy:
// Weblogic's JMS setup on Grails
jndiTemplate(org.springframework.jndi.JndiTemplate) {
environment = [
"java.naming.factory.initial" : "weblogic.jndi.WLInitialContextFactory",
"java.naming.provider.url" : "t3://host.name.mustbe.same.as.configured.on.server.side:port_number",
"java.naming.security.principal" : "wlsadmin",
"java.naming.security.credentials": "password"
]
}
//
// listener
//
jmsListenerConnectionFactory(org.springframework.jndi.JndiObjectFactoryBean) {
jndiTemplate = ref(jndiTemplate)
jndiName = "jms.checkonserver.QueueConnectionFactory"
}
jmsListenerDestinationResolver(org.springframework.jms.support.destination.JndiDestinationResolver) {
jndiTemplate = ref(jndiTemplate)
cache = false
}
userListenerCredentialsConnectionFactory(org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter){
targetConnectionFactory = ref(jmsListenerConnectionFactory)
}
standardListenerJmsTemplate(org.springframework.jms.core.JmsTemplate) {
connectionFactory = ref(userListenerCredentialsConnectionFactory)
destinationResolver = ref(jmsListenerDestinationResolver)
}
jmsListenerMessageListener(org.springframework.jms.listener.adapter.MessageListenerAdapter, ref("myListenerService")) {
defaultListenerMethod = "onMessage"
}
standardListenerJmsListenerContainer(org.springframework.jms.listener.DefaultMessageListenerContainer) {
connectionFactory = ref(jmsListenerConnectionFactory)
destinationResolver = ref(jmsListenerDestinationResolver)
messageListener = jmsListenerMessageListener
destinationName = "jms.checkonserver.MessagesQueue"
}
in services/myListenerService.groovy:
package app
class MyListenerService {
static transactional = false
static scope = "prototype"
def onMessage(msg) {
log.info "JMS msg received."
try {
String txtmsg = new String(msg as String)
log.info txtmsg
} catch (e) {
log.error e
}
}
}
Setting up JMS sender :
in conf/spring/resources.groovy:
jmsSenderConnectionFactory( org.springframework.jndi.JndiObjectFactoryBean) {
jndiTemplate = ref(jndiTemplate)
jndiName = "jms.checkonseerver.QueueConnectionFactory"
}
jmsSenderDestinationResolver(org.springframework.jms.support.destination.JndiDestinationResolver) {
jndiTemplate = ref(jndiTemplate)
cache = false
}
userSenderCredentialsConnectionFactory(org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter){
targetConnectionFactory = ref(jmsSenderConnectionFactory)
}
standardSenderJmsTemplate(org.springframework.jms.core.JmsTemplate) {
connectionFactory = ref(userSenderCredentialsConnectionFactory) //
destinationResolver = ref(jmsSenderDestinationResolver)
}
in service/myJmsSenderService.groovy:
package app
import org.springframework.jms.core.MessageCreator
import javax.jms.JMSException
import javax.jms.Message
import javax.jms.Session
class MyJmsSenderService {
static transactional = false
static scope = "prototype"
def standardSenderJmsTemplate
def sendMessage(txt) {
MessageCreator messageCreator = new MessageCreator() {
public Message createMessage(Session session) throws
JMSException {
return session.createTextMessage(txt)
}
}
standardSenderJmsTemplate.send( "jms.checkonserver.SendingQueue", messageCreator)
log.info "JMS message send: ${txt}"
}
}

Accessing LocalApplicationData Equivalent in Delphi

Using Delphi, how do I access the equivalent of .NET's System.Environment.SpecialFolder.LocalApplicationData variable (which works on any version of Windows)? I assumed I could just do:
dir := GetEnvironmentVariable('LOCALAPPDATA');
This works on Vista but XP doesn't seem to set that environment variable by default at least on my test machine.
In Delphi, the special system folder path constants are defined in ShlObj.DCU, and are referenced in the form of CSIDL_ followed by a symbolic name.
Example:
CSIDL_DESKTOPDIRECTORY returns the
path to the current desktop
CSIDL_PERSONAL is the My Documents directory
CSIDL___LOCAL_APPDATA is the (user name)\Local Settings\Application
Data directory
Here's a quick function that will return the appropriate special folder path when given the symbolic name. Make sure you include the SHLOBJ.DCU unit in your USES statement, and use the following:
function GetSpecialFolderPath(Folder: Integer; CanCreate: Boolean): string;
// Gets path of special system folders
//
// Call this routine as follows:
// GetSpecialFolderPath (CSIDL_PERSONAL, false)
// returns folder as result
//
var
FilePath: array [0..255] of char;
begin
SHGetSpecialFolderPath(0, #FilePath[0], FOLDER, CanCreate);
Result := FilePath;
end;
================================================================
For reference, the constants are as follows:
CSIDL_DESKTOP = $0000; { <desktop> }
CSIDL_INTERNET = $0001; { Internet Explorer (icon on desktop) }
CSIDL_PROGRAMS = $0002; { Start Menu\Programs }
CSIDL_CONTROLS = $0003; { My Computer\Control Panel }
CSIDL_PRINTERS = $0004; { My Computer\Printers }
CSIDL_PERSONAL = $0005; { My Documents. This is equivalent to CSIDL_MYDOCUMENTS in XP and above }
CSIDL_FAVORITES = $0006; { <user name>\Favorites }
CSIDL_STARTUP = $0007; { Start Menu\Programs\Startup }
CSIDL_RECENT = $0008; { <user name>\Recent }
CSIDL_SENDTO = $0009; { <user name>\SendTo }
CSIDL_BITBUCKET = $000a; { <desktop>\Recycle Bin }
CSIDL_STARTMENU = $000b; { <user name>\Start Menu }
CSIDL_MYDOCUMENTS = $000c; { logical "My Documents" desktop icon }
CSIDL_MYMUSIC = $000d; { "My Music" folder }
CSIDL_MYVIDEO = $000e; { "My Video" folder }
CSIDL_DESKTOPDIRECTORY = $0010; { <user name>\Desktop }
CSIDL_DRIVES = $0011; { My Computer }
CSIDL_NETWORK = $0012; { Network Neighborhood (My Network Places) }
CSIDL_NETHOOD = $0013; { <user name>\nethood }
CSIDL_FONTS = $0014; { windows\fonts }
CSIDL_TEMPLATES = $0015;
CSIDL_COMMON_STARTMENU = $0016; { All Users\Start Menu }
CSIDL_COMMON_PROGRAMS = $0017; { All Users\Start Menu\Programs }
CSIDL_COMMON_STARTUP = $0018; { All Users\Startup }
CSIDL_COMMON_DESKTOPDIRECTORY = $0019; { All Users\Desktop }
CSIDL_APPDATA = $001a; { <user name>\Application Data }
CSIDL_PRINTHOOD = $001b; { <user name>\PrintHood }
CSIDL_LOCAL_APPDATA = $001c; { <user name>\Local Settings\Application Data (non roaming) }
CSIDL_ALTSTARTUP = $001d; { non localized startup }
CSIDL_COMMON_ALTSTARTUP = $001e; { non localized common startup }
CSIDL_COMMON_FAVORITES = $001f;
CSIDL_INTERNET_CACHE = $0020;
CSIDL_COOKIES = $0021;
CSIDL_HISTORY = $0022;
CSIDL_COMMON_APPDATA = $0023; { All Users\Application Data }
CSIDL_WINDOWS = $0024; { GetWindowsDirectory() }
CSIDL_SYSTEM = $0025; { GetSystemDirectory() }
CSIDL_PROGRAM_FILES = $0026; { C:\Program Files }
CSIDL_MYPICTURES = $0027; { C:\Program Files\My Pictures }
CSIDL_PROFILE = $0028; { USERPROFILE }
CSIDL_SYSTEMX86 = $0029; { x86 system directory on RISC }
CSIDL_PROGRAM_FILESX86 = $002a; { x86 C:\Program Files on RISC }
CSIDL_PROGRAM_FILES_COMMON = $002b; { C:\Program Files\Common }
CSIDL_PROGRAM_FILES_COMMONX86 = $002c; { x86 C:\Program Files\Common on RISC }
CSIDL_COMMON_TEMPLATES = $002d; { All Users\Templates }
CSIDL_COMMON_DOCUMENTS = $002e; { All Users\Documents }
CSIDL_COMMON_ADMINTOOLS = $002f; { All Users\Start Menu\Programs\Administrative Tools }
CSIDL_ADMINTOOLS = $0030; { <user name>\Start Menu\Programs\Administrative Tools }
CSIDL_CONNECTIONS = $0031; { Network and Dial-up Connections }
CSIDL_COMMON_MUSIC = $0035; { All Users\My Music }
CSIDL_COMMON_PICTURES = $0036; { All Users\My Pictures }
CSIDL_COMMON_VIDEO = $0037; { All Users\My Video }
CSIDL_RESOURCES = $0038; { Resource Directory }
CSIDL_RESOURCES_LOCALIZED = $0039; { Localized Resource Directory }
CSIDL_COMMON_OEM_LINKS = $003a; { Links to All Users OEM specific apps }
CSIDL_CDBURN_AREA = $003b; { USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning }
CSIDL_COMPUTERSNEARME = $003d; { Computers Near Me (computered from Workgroup membership) }
CSIDL_PROFILES = $003e;
See this article.
Edit:
As added in the comment by stukelly there is a lot more information available about the SHGetFolderPath() functionality. The Delphi VCL really should have functionality for getting standard paths, and if Embarcadero is indeed going to have another Delphi-like tool on another OS this will be all the more important. For a multi-platform implementation of system standard paths see also the documentation of wxStandardPaths in wxWidgets. On MSW this uses the various CSIDL_XXX constants.
Assuming you can make WinAPI calls from Delphi (which ISTR you can), you used to be able to do that with an API call (something like GetSystemFolder or GetUserDataFolder). It's been a while since I've had to do that, but I think you can now do it with SHGetFolderPath, by passing in CSIDL_LOCAL_APPDATA.

Resources