001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.pm.graphic.frames;
051:
052: import java.awt.Container;
053: import java.awt.HeadlessException;
054: import java.net.MalformedURLException;
055: import java.net.URL;
056: import java.util.HashMap;
057: import java.util.Map;
058: import java.util.concurrent.locks.Lock;
059: import java.util.concurrent.locks.ReentrantLock;
060:
061: import javax.swing.RootPaneContainer;
062: import javax.swing.SwingUtilities;
063:
064: import org.apache.commons.collections.Closure;
065: import org.openproj.util.UpdateChecker;
066:
067: import com.projity.company.DefaultUser;
068: import com.projity.configuration.Configuration;
069: import com.projity.configuration.ConfigurationReader;
070: import com.projity.configuration.Dictionary;
071: import com.projity.configuration.Settings;
072: import com.projity.dialog.LicenseDialog;
073: import com.projity.dialog.LoginDialog;
074: import com.projity.dialog.LoginForm;
075: import com.projity.dialog.TipOfTheDay;
076: import com.projity.dialog.UserInfoDialog;
077: import com.projity.job.Mutex;
078: import com.projity.pm.task.Project;
079: import com.projity.server.access.PartnerInfo;
080: import com.projity.session.Session;
081: import com.projity.session.SessionFactory;
082: import com.projity.strings.Messages;
083: import com.projity.util.Alert;
084: import com.projity.util.Environment;
085:
086: public abstract class StartupFactory {
087: public static final String defaultServerUrl = Settings.SITE_HOME;
088: private static final int NUM_INVALID_LOGINS = 3;
089:
090: protected String serverUrl = null;
091: protected String[] projectUrls = null;
092: protected String login = null;
093: protected String password = null;
094: protected Map credentials = new HashMap();
095: protected long projectId;
096:
097: protected StartupFactory() {
098: // System.out.println("---------- StartupFactory");
099: }
100:
101: /**
102: * Used to test restoring of workspace to simulate applet restart
103: * @param old
104: * @return
105: */
106: public GraphicManager restart(GraphicManager old) {
107: RootPaneContainer con = (RootPaneContainer) old.getContainer();
108: old.encodeWorkspace();
109: old.cleanUp();
110: con.getContentPane().removeAll();
111: GraphicManager g = instanceFromExistingSession((Container) con);
112: // g.decodeWorkspace();
113:
114: // System.out.println("restarted");
115: return g;
116: }
117:
118: public GraphicManager instanceFromExistingSession(
119: Container container) {
120: long t = System.currentTimeMillis();
121: // System.out.println("---------- StartupFactory instanceFromExistingSession#1");
122: final GraphicManager graphicManager = new GraphicManager(
123: container);
124: graphicManager.setStartupFactory(this );
125: SessionFactory.getInstance().setJobQueue(
126: graphicManager.getJobQueue());
127: //if (Environment.isNewLook())
128: graphicManager.initLookAndFeel();
129: // System.out.println("---------- StartupFactory instanceFromExistingSession#1 done in "+(System.currentTimeMillis()-t)+" ms");
130: SwingUtilities.invokeLater(new Runnable() {
131:
132: public void run() {
133: long t = System.currentTimeMillis();
134: // System.out.println("---------- StartupFactory instanceFromExistingSession#2");
135: graphicManager.initView();
136: // System.out.println("---------- StartupFactory instanceFromExistingSession#2 done in "+(System.currentTimeMillis()-t)+" ms");
137: }
138: });
139: // graphicManager.invalidate();
140: return graphicManager;
141: }
142:
143: public GraphicManager instanceFromNewSession(Container container,
144: boolean doWelcome) {
145: long t = System.currentTimeMillis();
146: // System.out.println("---------- StartupFactory instanceFromNewSession#1 main");
147: Environment.setClientSide(true);
148:
149: Thread loadConfigThread = new Thread("loadConfig") {
150: public void run() {
151: long t = System.currentTimeMillis();
152: // System.out.println("---------- StartupFactory instanceFromNewSession#1 doLoadConfig");
153: doLoadConfig();
154: // System.out.println("---------- StartupFactory instanceFromNewSession#1 doLoadConfig done in "+(System.currentTimeMillis()-t)+" ms");
155: }
156: };
157: loadConfigThread.start();
158:
159: GraphicManager graphicManager = null;
160: //String projectUrl[]=null;
161: try {
162: graphicManager = new GraphicManager(
163: /*projectUrl,*/serverUrl, container);
164: graphicManager.setStartupFactory(this );
165: } catch (HeadlessException e) {
166: e.printStackTrace();
167: }
168: graphicManager.setConnected(false);
169:
170: if (!doLogin(graphicManager))
171: return null;
172: //if (Environment.isNewLook())
173: graphicManager.initLookAndFeel();
174:
175: SessionFactory.getInstance().setJobQueue(
176: graphicManager.getJobQueue());
177:
178: PartnerInfo partnerInfo = null;
179: if (!Environment.getStandAlone()) {
180: Session session = SessionFactory.getInstance().getSession(
181: false);
182: try {
183: partnerInfo = (PartnerInfo) SessionFactory.call(
184: session, "retrievePartnerInfo", null, null);
185: } catch (Exception e) {
186: e.printStackTrace();
187: }
188: }
189:
190: // System.out.println("---------- StartupFactory instanceFromNewSession#1 main done in "+(System.currentTimeMillis()-t)+" ms");
191: try {
192: loadConfigThread.join();
193: } catch (InterruptedException e1) {
194: e1.printStackTrace();
195: }
196:
197: t = System.currentTimeMillis();
198: // System.out.println("---------- StartupFactory instanceFromNewSession#2");
199:
200: //graphicManager.showWaitCursor(true); //TODO use a progress bar - maybe a Job
201: if (partnerInfo != null) {
202:
203: if (partnerInfo.getConfigurationXML() != null) {
204: ConfigurationReader.readString(partnerInfo
205: .getConfigurationXML(), Configuration
206: .getInstance());
207: Configuration.getInstance().setDonePopulating();
208: }
209: if (partnerInfo.getViewXML() != null) {
210: ConfigurationReader.readString(
211: partnerInfo.getViewXML(), Dictionary
212: .getInstance());
213: }
214: }
215:
216: final GraphicManager gm = graphicManager;
217: graphicManager.beginInitialization();
218: try {
219:
220: graphicManager.initView();
221:
222: doStartupAction(graphicManager, 0, projectUrls, doWelcome);
223:
224: doPostInitView(graphicManager.getContainer());
225: } finally {
226: graphicManager.finishInitialization();
227: }
228: return graphicManager;
229: }
230:
231: public void doLoadConfig() {
232: com.projity.init.Init.initialize();
233: }
234:
235: public void doPostInitView(Container container) {
236: }
237:
238: public boolean doLogin(GraphicManager graphicManager) {
239: if (Environment.getStandAlone()) {
240: // graphicManager.getFrame().setVisible(true);
241: Environment.setUser(new DefaultUser());
242: return true;
243: }
244: credentials.put("serverUrl", serverUrl);
245: getCredentials();
246: Environment.setNewLook(true);
247:
248: int badLoginCount = 0;
249: while (true) { // until a good login or exit because of too many bad
250: // graphicManager.getFrame().setVisible(true);
251: if (login == null || password == null || badLoginCount > 0) {
252: URL loginUrl = null;
253: if (login == null || password == null) {
254: try {
255: loginUrl = new URL(serverUrl + "/login");
256: } catch (MalformedURLException e) {
257: }
258: }
259: LoginForm form = LoginDialog.doLogin(graphicManager
260: .getFrame(), loginUrl); // it's actually a singleton
261: if (form.isCancelled())
262: System.exit(-1);
263: if (form.isUseMenus())
264: Environment.setNewLook(false);
265:
266: login = form.getLogin();
267: password = form.getPassword();
268: }
269:
270: if ("_SA".equals(login) || Environment.getStandAlone()) {// for testing purposes!
271: Environment.setStandAlone(true);
272: Environment.setUser(new DefaultUser());
273: break;
274: } else {
275: credentials.put("login", login);
276: credentials.put("password", password);
277:
278: SessionFactory.getInstance()
279: .setCredentials(credentials);
280: try {
281: Session session = SessionFactory.getInstance()
282: .getSession(false);
283: System.out.println("logging in");
284: final GraphicManager gm = graphicManager;
285: SessionFactory.callNoEx(session, "login",
286: new Class[] { Closure.class },
287: new Object[] { new Closure() {
288: public void execute(Object arg0) {
289: gm.setConnected(true);
290:
291: }
292: } });
293: if (!((Boolean) SessionFactory.callNoEx(session,
294: "isLicensedToRunClient", null, null))
295: .booleanValue()) {
296: Alert.error(Messages
297: .getString("Error.roleCantRunClient"));
298: abort();
299: return false;
300: }
301:
302: // System.out.println("Application started with args: credentials=" + credentials.get("login") + " name " + session.getUser().getName() + " Roles " + session.getUser().getServerRoles());
303: break;
304: // TODO test if login is valid. If not, reshow login dialog
305: } catch (Exception e) {
306: if (Session.EXPIRED.equals(e.getMessage())) {
307: Alert.error(Messages
308: .getString("Error.accountExpired"));
309: abort();
310: return false;
311:
312: }
313: System.out.println("failure " + e);
314: badLoginCount++;
315: SessionFactory.getInstance().clearSessions();
316:
317: if (badLoginCount == NUM_INVALID_LOGINS) {
318: Alert.error(Messages
319: .getString("Login.tooManyBad"));
320: abort();
321: return false;
322: } else {
323: Alert.error(Messages.getString("Login.error"));
324: }
325: }
326: }
327: }
328: return true;
329: }
330:
331: protected abstract void abort();
332:
333: protected void getCredentials() {
334: }
335:
336: public void doStartupAction(final GraphicManager gm,
337: final long projectId, final String[] projectUrls,
338: final boolean welcome) {
339: if (Environment.isClientSide()) {
340: if (projectId > 0) {
341: gm.loadDocument(projectId, true, false, new Closure() {
342: public void execute(Object arg0) {
343: Project project = (Project) arg0;
344: DocumentFrame frame = gm.getCurrentFrame();
345: if (frame != null
346: && frame.getProject().getUniqueId() != projectId) {
347: gm.switchToProject(projectId);
348: }
349: }
350: });
351: } else if (projectUrls != null && projectUrls.length > 0) {
352: gm.loadLocalDocument(projectUrls[0], !Environment
353: .getStandAlone());
354: } else {
355: SwingUtilities.invokeLater(new Runnable() {
356: public void run() {
357: if (Environment.isOpenProj()) {
358: LicenseDialog.showDialog(gm.getFrame(),
359: false);
360: UserInfoDialog.showDialog(gm.getFrame(),
361: false);
362: UpdateChecker.checkForUpdateInBackground();
363: }
364: if (welcome) {
365: if (Environment.isOpenProj()) {
366: //LicenseDialog.showDialog(gm.getFrame(),false);
367: TipOfTheDay.showDialog(gm.getFrame(),
368: false);
369: }
370: // gm.initLookAndFeel();
371: gm.doWelcomeDialog();
372: }
373: }
374: });
375:
376: }
377: }
378:
379: }
380:
381: }
|