Pass in window parameter on startup

Hi guys: Our apps continue to expand here, and I am thinking of consolidating them into fewer, larger ones. Many are opened by users from an intranet menu item. I would like to simplify them getting to the screens they want by having a window become current (on opening the app) based on the intranet menu item they click. For example Tank Levels takes them to the tank window, Utilities Consumption to Utilities window, etc. Is it possible to pass in a window argument to Factory PMI when opening the app? TIA D. Lewis

Parameter passing into the application is a great idea! That fits really well with “executive dashboard” ideas for small integrated applets. I associate this with screens that don’t require users to login.

As of now you can get half way with either of these 2 options:
-Require a login screen. Write a Global Event Script (on startup) that opens different screens based on their username.
-Under edit project for a specific project go to project properties, there you can specify an “auto-login” username and password.

I’ll get Application parameter passing in as a feature request. It’s a great idea.

I suspect that there is a bit of trickery that could be done right now to accomplish this, thanks to the retargeting feature.

Retargeting allows you to open one project from inside of another one (making it seem like you’re just switching windows). Further, it lets you pass in any number of arbitrary parameters which end up as global jyton variables, which you could then respond to in the global startup script. The only trick is to emulate this through your web links… which may or may not be possible.

I’ll try to find out, Carl’s the one who would know, but he’s out of the office today. In the mean time, you may want to look into retargeting in general. If nothing else, you could have buttons/links inside the apps to bounce around between projects. Check out the fpmi.system.retarget function in the documentation.

Hope this helps a bit,

Thanks Colby, I’ll check it out. David

David,

Unfortunately, passing different parameters into an application from an HTML link isn’t a viable option due to Java Web Start’s architecture.

You have two options that I can think of. One is to break your project(s) apart into subprojects that correspond to these existing intranet links that you mentioned. Your projects can then retarget between themselves so that once one of the projects is launched, the user has a seamless experience switching between the projects.

The other option is to have everything in one project, and re-make the intranet menu structure within FactoryPMI (via the menu bar, or a docked window), and change the intranet menu to simply launch your project.

Let me know if you’d like help implementing either one of these options,

Carl:

The option of having one project target another sounds most workable. I take it to mean that a menu item in one project will launch another project. Is that correct?

In the case of our current intranet and its menu, I have a hyperlink to the java file for the various projects. Would I use that in the code section for the runtime menu within PMI in order to launch another project? TIA D. Lewis

David,

Actually, you wouldn’t ‘launch’ the other project, per se. (you could, by calling fpmi.net.openURL(), but this would result in two FactoryPMI clients running at a time, which wouldn’t be optimal, and wouldn’t work well if these projects run in full screen exclusive mode)
You instead use the ‘retargetting’ feature that was introduced in FactoryPMI 1.7.0. What this does is to switch the currently running runtime into another project. The user credentials that were used to log into the first project are re-used to log into the second one. If they fail, the user is asked to log in again to the other project. To do this, you simply invoke the fpmi.system.retarget function. For instance, to retarget to a project named “Tanks” on the same Gateway as the currently running project, you would do this:

fpmi.system.retarget("Tanks")

There are lots of optional arguments to the retarget function, including a different Gateway address, global Jython parameters to pass, and a list of windows to open if you don’t want the project’s default startup windows to open. See the documentation in the technical reference for more details.

I see this topic is a bit old, and there’s another one (Open Windows Dynamically When Starting App ) that also addresses startup parameters in the URL but…is this still un-doable in FPMI?

I know that I can capture the login and IP address of the client (and yes, I could put these in a table to open windows or set variables that I need) but that doesn’t work for an application I’m developing since:

  1. I want the app to be as hands off as possible- auto login, production line aware
  2. All the IPs are on the same nextwork and, as much as IT moves computers around and as many as there are out there, it’d take a daily effort do maintain an table of computers per line.

Passing a parameter in the URL, to me, is essiential, especially in light of how easy it is to get FPMI to multiple clients. Any thoughts?

A couple of approaches come to mind.

  1. Store startup parameters in a local OS file with a standard name in a standard folder. Upon startup, read the file using the fpmi.file module to get the parameters. If necessary, you can start FPMI with a cmd file that populates the file with dynamic data and/or optional command line parameters.

  2. Use the functions in the fpmi.net, fpmi.security, and/or fpmi.system modules to get the information you need.

I understand why this could be helpful, but the JWS architecture really doesn’t allow for it. Describe for me why this is essential for you.

Another approach could be to use the client’s browser history to find the parameters which were passed in the URL…

[code]import time
from struct import *
from urllib import unquote

Find IE’s daily history file

filename = “”
tomorrow = time.localtime(time.time()+86400)
os_name = fpmi.system.getProperty(“os.name”)

if os_name == “Windows 2000” or os_name == “Windows 2003” or os_name == “Windows XP”:
filename = “C:\Documents and Settings\”
filename += fpmi.system.getProperty(“user.name”)
filename += “\Local Settings\History\History.IE5\MSHist01”
filename += time.strftime("%Y%m%d")
filename += time.strftime("%Y%m%d", tomorrow)
filename += “\index.dat”
else:
filename = “C:\Users\”
filename += fpmi.system.getProperty(“user.name”)
filename += “\AppData\Local\Microsoft\Windows\History\History.IE5\MSHist01”
filename += time.strftime("%Y%m%d")
filename += time.strftime("%Y%m%d", tomorrow)
filename += “\index.dat”

proj = fpmi.system.getProjectName()
proj += “.jnlp”

if filename and fpmi.file.fileExists(filename):

data = fpmi.file.readFileAsString(filename)

p = 0x5000
latest_p = 0
latest_num_blocks = 0L
latest_access = 0L

#
# Find URL record with most recent access to 'proj'
#
while (p < len(data)):

	# Find record signature
	p = data.find("URL ", int(p))

	if p < 0: break

	# Signature must be on 128 byte boundary
	if p % 128:
		p = p + 4 
		continue

	# Read num_blocks and datetime of access
	# Note: Datetime is in FATTIME format but we will simply
	#       convert it to a long which is good enough for
	#       finding the most recent access
	num_blocks,d,t = unpack('<4xL72xHH',data[p:p+84])
	access = (long(d)<<16) + long(t)
	
	if num_blocks <= 0: break

	# Is our project in this record ?
	q = data.find(proj, int(p+104), int(p+(num_blocks*128)))

	if q > 0:

		if access > latest_access:
			latest_p = p
			latest_num_blocks = num_blocks
			latest_access = access

	p = p + num_blocks*128

#
# If a record has been found then extract it's query string
#
query = ""

if latest_p:
	p1 = data.find(proj, int(latest_p+104), int(latest_p+(latest_num_blocks*128)))

	if p1 > 0 and data[p1+len(proj)] == '?':
		p1 = p1 + len(proj) + 1
		p2 = data.find('\0', p1)
		if p2 > 0:
			query = data[p1:p2]

#
# If we have a query string then extract parameters 
# and do what you like with them.
#
fpmi.nav.openWindow("Menu") # Default window
if query:

	pairs = query.split("&")

	for pair in pairs:
		param = pair.split("=")
		key = unquote(param[0])
		val = unquote(param[1])

		if key == "open":
			fpmi.nav.swapTo(val)

		elif key == "greeting":
			fpmi.tag.writeToTag("[Client]greeting",val)

		else:
			fpmi.gui.messageBox("Unknown parameter: "+key+" = "+val)[/code]

Caveats:
[ul]
[li]The code shown only currently supports IE[/li]
[li]The IE index.dat file format is not formally documented so this solution is based on reverse engineering[/li]
[li]I’ve only tested this on Windows 2003,XP and Vista with IE 7[/li]
[li]I’m a python newbie so check for mistakes :wink:[/li][/ul]

The attached example accepts 2 parameters:
[ul]
[li]open = Window to open on startup[/li]
[li]greeting = A greeting displayed on the window[/li][/ul]

Eg:
http://localhost:8080/gateway/launch/myproject.jnlp?open=Window2&greeting=Good%20Morning
myproject.fpmi (26.3 KB)

Wow, that is the craziest thing I’ve seen all week…

Congrats, you get the awesome hack of the week award, hands down.