Revision: 3298
Author: ferguson.sebastian
Date: Tue Feb 16 14:02:41 2010
Log: A project's target database is no longer a child of the project, it is
a child of the SPObjectRoot. Target databases are marked with the playpen
database tag. Architect project importer now loads the entire project into
the jcr, as it can now call persist object on the ArchitectProject. An
exception was previously thrown in the SPJSONMessageDecoder when the parent
of an object has no UUID. This was a problem for the ArchitectProject which
has no parent.
http://code.google.com/p/power-architect/source/detail?r=3298
Modified:
/trunk/regress/ca/sqlpower/architect/ArchitectProjectTest.java
/trunk/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java
/trunk/regress/ca/sqlpower/architect/swingui/TestingArchitectSwingSession.java
/trunk/src/ca/sqlpower/architect/ArchitectProject.java
/trunk/src/ca/sqlpower/architect/ProjectLoader.java
/trunk/src/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
/trunk/src/ca/sqlpower/architect/profile/ProfileManagerImpl.java
/trunk/src/ca/sqlpower/architect/profile/ProfileSettings.java
/trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
/trunk/src/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
=======================================
--- /trunk/regress/ca/sqlpower/architect/ArchitectProjectTest.java Thu Feb
11 14:16:30 2010
+++ /trunk/regress/ca/sqlpower/architect/ArchitectProjectTest.java Tue Feb
16 14:02:41 2010
@@ -64,7 +64,7 @@
public void testChildPositionOffset() throws Exception {
assertEquals(1,
objectUnderTest.childPositionOffset(ProfileManagerImpl.class));
}
-
+
@Override
public void testPersisterCreatesNewObjects() throws Exception {
//The ArchitectProject is the root of the SPObject tree. This
=======================================
--- /trunk/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java
Mon Feb 8 10:12:47 2010
+++ /trunk/regress/ca/sqlpower/architect/swingui/TestSwingUIProject.java
Tue Feb 16 14:02:41 2010
@@ -365,6 +365,7 @@
ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
assertNotNull(byteArrayOutputStream);
project.save(byteArrayOutputStream,ENCODING);
+ System.out.println(byteArrayOutputStream.toString());
ArchitectSwingSessionContext context = session.getContext();
ArchitectSwingSession session2 = context.createSession(false);
=======================================
---
/trunk/regress/ca/sqlpower/architect/swingui/TestingArchitectSwingSession.java
Fri Feb 12 07:43:48 2010
+++
/trunk/regress/ca/sqlpower/architect/swingui/TestingArchitectSwingSession.java
Tue Feb 16 14:02:41 2010
@@ -45,7 +45,6 @@
import
ca.sqlpower.architect.swingui.ArchitectSwingSessionImpl.ColumnVisibility;
import ca.sqlpower.architect.swingui.olap.OLAPEditSession;
import ca.sqlpower.architect.undo.ArchitectUndoManager;
-import ca.sqlpower.object.ObjectDependentException;
import ca.sqlpower.sql.DataSourceCollection;
import ca.sqlpower.sql.JDBCDataSource;
import ca.sqlpower.sql.SPDataSource;
@@ -73,8 +72,6 @@
private PlayPen playpen;
private ArchitectUndoManager undoManager;
private DBTree sourceDatabases;
- private SQLObjectRoot rootObject;
- private ProfileManager profileManager;
private CompareDMSettings compareDMSettings;
private DDLGenerator ddlGenerator;
private KettleJob kettleJob;
@@ -101,12 +98,9 @@
}
};
this.delegateSession = new ArchitectSessionImpl(context, "test");
- profileManager = new ProfileManagerImpl();
- ((ProfileManagerImpl) profileManager).setUserPrompterFactory(this);
+ ((ProfileManagerImpl)
delegateSession.getProfileManager()).setUserPrompterFactory(this);
project = new SwingUIProjectLoader(this);
userSettings = context.getUserSettings();
- rootObject = new SQLObjectRoot();
- rootObject.addChild(getTargetDatabase());
sourceDatabases = new DBTree(this);
playpen = RelationalPlayPenFactory.createPlayPen(this,
sourceDatabases);
undoManager = new ArchitectUndoManager(playpen);
@@ -153,7 +147,7 @@
}
public ProfileManager getProfileManager() {
- return profileManager;
+ return delegateSession.getProfileManager();
}
public CoreUserSettings getUserSettings() {
@@ -210,22 +204,7 @@
}
public void setSourceDatabaseList(List<SQLDatabase> databases) throws
SQLObjectException {
- try {
- rootObject.begin("Setting source database list");
- for (int i = rootObject.getChildCount()-1; i >= 0; i--) {
- rootObject.removeChild(rootObject.getChild(i));
- }
- for (SQLDatabase db : databases) {
- rootObject.addChild(db);
- }
- rootObject.commit();
- } catch (IllegalArgumentException e) {
- rootObject.rollback("Could not remove child: " +
e.getMessage());
- throw new RuntimeException(e);
- } catch (ObjectDependentException e) {
- rootObject.rollback("Could not remove child: " +
e.getMessage());
- throw new RuntimeException(e);
- }
+ delegateSession.setSourceDatabaseList(databases);
}
public KettleJob getKettleJob() {
@@ -285,7 +264,7 @@
}
public SQLObjectRoot getRootObject() {
- return rootObject;
+ return delegateSession.getRootObject();
}
public boolean isShowPkTag() {
=======================================
--- /trunk/src/ca/sqlpower/architect/ArchitectProject.java Fri Feb 12
10:53:21 2010
+++ /trunk/src/ca/sqlpower/architect/ArchitectProject.java Tue Feb 16
14:02:41 2010
@@ -24,7 +24,6 @@
import java.util.Collections;
import java.util.List;
-import ca.sqlpower.architect.ddl.DDLGenerator;
import ca.sqlpower.architect.profile.ProfileManager;
import ca.sqlpower.object.AbstractSPObject;
import ca.sqlpower.object.ObjectDependentException;
@@ -35,6 +34,7 @@
import ca.sqlpower.object.annotation.NonBound;
import ca.sqlpower.object.annotation.NonProperty;
import ca.sqlpower.object.annotation.Transient;
+import ca.sqlpower.object.annotation.ConstructorParameter.ParameterType;
import ca.sqlpower.sql.JDBCDataSource;
import ca.sqlpower.sqlobject.SQLDatabase;
import ca.sqlpower.sqlobject.SQLObject;
@@ -59,15 +59,14 @@
@SuppressWarnings("unchecked")
public static List<Class<? extends SPObject>> allowedChildTypes =
Collections.unmodifiableList(new ArrayList<Class<? extends
SPObject>>(
- Arrays.asList(SQLObjectRoot.class, ProfileManager.class,
SQLDatabase.class)));
+ Arrays.asList(SQLObjectRoot.class, ProfileManager.class)));
/**
* There is a 1:1 ratio between the session and the project.
*/
private ArchitectSession session;
private final SQLObjectRoot rootObject;
- private ProfileManager profileManager;
- private final SQLDatabase db;
+ private ProfileManager profileManager;
/**
* Constructs an architect project. The init method must be called
immediately
@@ -75,26 +74,25 @@
* @throws SQLObjectException
*/
public ArchitectProject() throws SQLObjectException {
- this(new SQLObjectRoot(), new SQLDatabase());
+ this(new SQLObjectRoot());
+
+ SQLDatabase targetDatabase = new SQLDatabase();
+ targetDatabase.setPlayPenDatabase(true);
+ rootObject.addChild(targetDatabase, 0);
}
/**
* The init method for this project must be called immediately after
this
* object is constructed.
*
- * @param sourceRootObject
+ * @param rootObject
* The root object that holds all of the source databases
for the
* current project.
- * @param targetDB
- * The target database that will represent the play pen and
be
- * acted on by other parts of Architect.
*/
@Constructor
- public
ArchitectProject(@ConstructorParameter(propertyName="rootObject")
SQLObjectRoot sourceRootObject,
- @ConstructorParameter(propertyName="targetDatabase")
SQLDatabase targetDB)
+ public
ArchitectProject(@ConstructorParameter(isProperty=ParameterType.CHILD,
propertyName="rootObject") SQLObjectRoot rootObject)
throws SQLObjectException {
- this.rootObject = sourceRootObject;
- this.db = targetDB;
+ this.rootObject = rootObject;
}
/**
@@ -104,7 +102,7 @@
this.session = session;
rootObject.addSQLObjectPreEventListener(new
SourceObjectIntegrityWatcher(session));
rootObject.setParent(this);
- db.setParent(this);
+ setName("Architect Project");
}
/**
@@ -129,9 +127,6 @@
return (SQLDatabase) obj;
}
}
- if (db.getDataSource().equals(ds)) {
- return db;
- }
SQLDatabase db = new SQLDatabase(ds);
getRootObject().addChild(db);
return db;
@@ -140,19 +135,28 @@
}
}
- @NonProperty
+ @Transient @Accessor
public SQLDatabase getTargetDatabase() {
- return db;
+ for (SQLDatabase db : rootObject.getChildren(SQLDatabase.class)) {
+ if (db.isPlayPenDatabase()) {
+ return db;
+ }
+ }
+ throw new IllegalStateException("No target database!");
}
@NonProperty
public void setSourceDatabaseList(List<SQLDatabase> databases) throws
SQLObjectException {
SQLObject root = getRootObject();
+ SQLDatabase targetDB = getTargetDatabase();
try {
root.begin("Setting source database list");
for (int i = root.getChildCount()-1; i >= 0; i--) {
root.removeChild(root.getChild(i));
}
+ if (targetDB != null) {
+ root.addChild(targetDB);
+ }
for (SQLDatabase db : databases) {
root.addChild(db);
}
@@ -197,10 +201,6 @@
return 0;
} else if (ProfileManager.class.isAssignableFrom(childType)) {
return 1;
- } else if (DDLGenerator.class.isAssignableFrom(childType)) {
- return 2;
- } else if (SQLDatabase.class.isAssignableFrom(childType)) {
- return 3;
} else {
throw new IllegalArgumentException();
}
@@ -215,8 +215,9 @@
public List<SPObject> getChildren() {
List<SPObject> allChildren = new ArrayList<SPObject>();
allChildren.add(rootObject);
- allChildren.add(profileManager);
- allChildren.add(db);
+ if (profileManager != null) {
+ allChildren.add(profileManager);
+ }
return allChildren;
}
@@ -226,7 +227,6 @@
}
public void removeDependency(SPObject dependency) {
- db.removeDependency(dependency);
rootObject.removeDependency(dependency);
profileManager.removeDependency(dependency);
}
=======================================
--- /trunk/src/ca/sqlpower/architect/ProjectLoader.java Mon Feb 8 10:12:47
2010
+++ /trunk/src/ca/sqlpower/architect/ProjectLoader.java Tue Feb 16 14:02:41
2010
@@ -217,9 +217,7 @@
}
SQLObject dbConnectionContainer = ((SQLObject)
getSession().getRootObject());
-
dbConnectionContainer.addChild(getSession().getTargetDatabase(), 0);
- getSession().getTargetDatabase().setPlayPenDatabase(true);
-
+
// hook up data source parent types
for (SQLDatabase db :
dbConnectionContainer.getChildren(SQLDatabase.class)) {
JDBCDataSource ds = db.getDataSource();
=======================================
---
/trunk/src/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Fri Feb 12 15:21:05 2010
+++
/trunk/src/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Tue Feb 16 14:02:41 2010
@@ -197,9 +197,9 @@
updater.start();
final SPPersisterListener listener = new
SPPersisterListener(jsonPersister,
- new SessionPersisterSuperConverter(dataSourceCollection,
getWorkspace().getRootObject()));
-
- SQLPowerUtils.listenToHierarchy(getWorkspace().getRootObject(),
listener);
+ new SessionPersisterSuperConverter(dataSourceCollection,
getWorkspace()));
+
+ SQLPowerUtils.listenToHierarchy(getWorkspace(), listener);
addSessionLifecycleListener(new
SessionLifecycleListener<ArchitectSession>() {
public void
sessionClosing(SessionLifecycleEvent<ArchitectSession> e) {
@@ -211,7 +211,7 @@
public void persistProjectToServer() throws SPPersistenceException {
final SPPersisterListener tempListener = new
SPPersisterListener(jsonPersister,
new SessionPersisterSuperConverter(dataSourceCollection,
getWorkspace()));
- tempListener.persistObject(getWorkspace().getRootObject(), 0);
+ tempListener.persistObject(getWorkspace(), 0);
}
public ArchitectProject getSystemWorkspace() {
@@ -474,6 +474,7 @@
try {
currentRevision++;
+ System.out.println(message.toString());
URI serverURI = getServerURI();
HttpPost postRequest = new HttpPost(serverURI);
@@ -777,10 +778,18 @@
"data-sources/" + type + "/" + ds.getName());
}
}
-
+
private static class JSONResponseHandler implements
ResponseHandler<String> {
- public String handleResponse(HttpResponse response) throws
ClientProtocolException, IOException {
+ /*
+ * Responses from the architect-enterprise resources should always be
bundled as
+ * a JSON object of the form {"responseKind":(data or
exception),"data":(data or stackTrace)}.
+ *
+ * This is an extension of the basic response handler which returns
data (if found), or
+ * reads, reconstructs, and re-throws an exception from a resource.
+ */
+
+ public String handleResponse(HttpResponse response) throws
ClientProtocolException, IOException {
try {
BufferedReader reader = new BufferedReader(
@@ -794,21 +803,28 @@
JSONObject message = new JSONObject(buffer.toString());
+ // Does the response contain data? If so, return it.
Communication
+ // with the resource has been successful.
if (message.getString("responseKind").equals("data")) {
return message.getString("data");
- } else if
(message.getString("responseKind").equals("exceptionStackTrace")) {
-
- JSONArray stackTraceStrings = new
JSONArray(message.getString("data"));
- StringBuffer stackTraceMessage = new StringBuffer();
- for (int i = 0; i < stackTraceStrings.length(); i++) {
- stackTraceMessage.append("\n(from resource)
at ").append(stackTraceStrings.get(i));
- }
-
- throw new Exception(stackTraceMessage.toString());
- } else {
- throw new Exception("Unable to parse response");
- }
-
+ } else {
+ // Does the response contain an exception? If so,
reconstruct, and then
+ // re-throw it. There has been an exception on the
server.
+ if
(message.getString("responseKind").equals("exceptionStackTrace")) {
+
+ JSONArray stackTraceStrings = new
JSONArray(message.getString("data"));
+ StringBuffer stackTraceMessage = new
StringBuffer();
+ for (int i = 0; i < stackTraceStrings.length();
i++) {
+
stackTraceMessage.append("\n").append(stackTraceStrings.get(i));
+ }
+
+ throw new Exception(stackTraceMessage.toString());
+
+ } else {
+ // This exception represents a(n epic)
client-server miscommunication
+ throw new Exception("Unable to parse response");
+ }
+ }
} catch (Exception ex) {
throw new RuntimeException(ex);
}
=======================================
--- /trunk/src/ca/sqlpower/architect/profile/ProfileManagerImpl.java Fri
Feb 12 10:54:03 2010
+++ /trunk/src/ca/sqlpower/architect/profile/ProfileManagerImpl.java Tue
Feb 16 14:02:41 2010
@@ -200,6 +200,7 @@
@Constructor
public ProfileManagerImpl() {
defaultProfileSettings.setParent(this);
+ setName("Profile Manager");
}
@Transient @Mutator
=======================================
--- /trunk/src/ca/sqlpower/architect/profile/ProfileSettings.java Fri Feb
12 08:29:11 2010
+++ /trunk/src/ca/sqlpower/architect/profile/ProfileSettings.java Tue Feb
16 14:02:41 2010
@@ -63,6 +63,10 @@
private int topNCount = 10;
+ public ProfileSettings() {
+ setName("Profile Settings");
+ }
+
@Accessor
public boolean isFindingAvg() {
return findingAvg;
=======================================
--- /trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
Fri Feb 12 07:43:48 2010
+++ /trunk/src/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
Tue Feb 16 14:02:41 2010
@@ -246,7 +246,6 @@
olapSchemaManager = new OLAPSchemaManager(this);
- delegateSession.getRootObject().addChild(getTargetDatabase());
this.sourceDatabases = new DBTree(this);
playPen = RelationalPlayPenFactory.createPlayPen(this,
sourceDatabases);
=======================================
---
/trunk/src/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
Fri Feb 12 09:08:50 2010
+++
/trunk/src/ca/sqlpower/architect/swingui/enterprise/ServerProjectsManagerPanel.java
Tue Feb 16 14:02:41 2010
@@ -191,8 +191,9 @@
}
} else {
serversModel.addElement("No Servers");
- }
-
+ servers.setEnabled(false);
+ }
+
projects = new JList(new DefaultListModel());
projects.addMouseListener(new MouseAdapter() {
@Override
@@ -266,8 +267,9 @@
try {
for (ProjectLocation pl :
ArchitectClientSideSession.getWorkspaceNames(serviceInfo)) {
model.addElement(pl);
- connected = true;
- }
+
+ }
+ connected = true;
} catch (Exception ex) {
model.removeAllElements();
model.addElement("Unable to get projects from server");