You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/12/08 15:56:01 UTC
[24/53] [partial] ISIS-188: making structure of component viewers
consistent
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/AbstractControlView.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/AbstractControlView.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/AbstractControlView.java
new file mode 100644
index 0000000..3824652
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/AbstractControlView.java
@@ -0,0 +1,505 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.control;
+
+import java.awt.event.KeyEvent;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.core.runtime.userprofile.Options;
+import org.apache.isis.viewer.dnd.drawing.Bounds;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Padding;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Click;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.ContentDrag;
+import org.apache.isis.viewer.dnd.view.DragEvent;
+import org.apache.isis.viewer.dnd.view.DragStart;
+import org.apache.isis.viewer.dnd.view.Feedback;
+import org.apache.isis.viewer.dnd.view.FocusManager;
+import org.apache.isis.viewer.dnd.view.InternalDrag;
+import org.apache.isis.viewer.dnd.view.KeyboardAction;
+import org.apache.isis.viewer.dnd.view.Placement;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.UserAction;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewAreaType;
+import org.apache.isis.viewer.dnd.view.ViewDrag;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.ViewState;
+import org.apache.isis.viewer.dnd.view.Viewer;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.base.Layout;
+
+public abstract class AbstractControlView implements View {
+ protected final UserAction action;
+ private final View parent;
+ private int width;
+ private int x;
+ private int y;
+ private int height;
+ private boolean isOver;
+ private boolean isPressed;
+
+ public AbstractControlView(final UserAction action, final View target) {
+ this.action = action;
+ this.parent = target;
+ }
+
+ @Override
+ public Axes getViewAxes() {
+ return new Axes();
+ }
+
+ @Override
+ public void addView(final View view) {
+ }
+
+ @Override
+ public Consent canChangeValue() {
+ return Veto.DEFAULT;
+ }
+
+ @Override
+ public boolean canFocus() {
+ return action.disabled(parent).isAllowed();
+ }
+
+ @Override
+ public boolean contains(final View view) {
+ return false;
+ }
+
+ @Override
+ public boolean containsFocus() {
+ return false;
+ }
+
+ @Override
+ public void contentMenuOptions(final UserActionSet menuOptions) {
+ }
+
+ @Override
+ public void debug(final DebugBuilder debug) {
+ }
+
+ @Override
+ public void debugStructure(final DebugBuilder b) {
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void drag(final ContentDrag contentDrag) {
+ }
+
+ @Override
+ public void drag(final InternalDrag drag) {
+ }
+
+ @Override
+ public void drag(final ViewDrag drag) {
+ }
+
+ @Override
+ public void dragCancel(final InternalDrag drag) {
+ }
+
+ @Override
+ public View dragFrom(final Location location) {
+ return null;
+ }
+
+ @Override
+ public void dragIn(final ContentDrag drag) {
+ }
+
+ @Override
+ public void dragOut(final ContentDrag drag) {
+ }
+
+ @Override
+ public DragEvent dragStart(final DragStart drag) {
+ return null;
+ }
+
+ @Override
+ public void dragTo(final InternalDrag drag) {
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ }
+
+ @Override
+ public void drop(final ContentDrag drag) {
+ }
+
+ @Override
+ public void drop(final ViewDrag drag) {
+ getParent().drop(drag);
+ }
+
+ @Override
+ public void editComplete(final boolean moveFocus, final boolean toNextField) {
+ }
+
+ @Override
+ public void entered() {
+ final View target = getParent();
+ final Consent consent = action.disabled(target);
+ final String actionText = action.getName(target) + " - " + (consent.isVetoed() ? consent.getReason() : action.getDescription(target));
+ getFeedbackManager().setAction(actionText);
+
+ isOver = true;
+ isPressed = false;
+ markDamaged();
+ }
+
+ @Override
+ public void exited() {
+ getFeedbackManager().clearAction();
+ isOver = false;
+ isPressed = false;
+ markDamaged();
+ }
+
+ public void exitedSubview() {
+ }
+
+ @Override
+ public void firstClick(final Click click) {
+ executeAction();
+ }
+
+ private void executeAction() {
+ final View target = getParent().getView();
+ if (action.disabled(target).isAllowed()) {
+ markDamaged();
+ getViewManager().saveCurrentFieldEntry();
+ action.execute(target.getWorkspace(), target, getLocation());
+ }
+ }
+
+ @Override
+ public void focusLost() {
+ }
+
+ @Override
+ public void focusReceived() {
+ }
+
+ @Override
+ public Location getAbsoluteLocation() {
+ final Location location = parent.getAbsoluteLocation();
+ getViewManager().getSpy().addTrace(this, "parent location", location);
+ location.add(x, y);
+ getViewManager().getSpy().addTrace(this, "plus view's location", location);
+ final Padding pad = parent.getPadding();
+ location.add(pad.getLeft(), pad.getTop());
+ getViewManager().getSpy().addTrace(this, "plus view's padding", location);
+ return location;
+ }
+
+ public boolean isOver() {
+ return isOver;
+ }
+
+ public boolean isPressed() {
+ return isPressed;
+ }
+
+ @Override
+ public int getBaseline() {
+ return 0;
+ }
+
+ @Override
+ public Bounds getBounds() {
+ return new Bounds(x, y, width, height);
+ }
+
+ @Override
+ public Content getContent() {
+ return null;
+ }
+
+ @Override
+ public int getId() {
+ return 0;
+ }
+
+ @Override
+ public FocusManager getFocusManager() {
+ return getParent() == null ? null : getParent().getFocusManager();
+ }
+
+ @Override
+ public Location getLocation() {
+ return new Location(x, y);
+ }
+
+ @Override
+ public Padding getPadding() {
+ return null;
+ }
+
+ @Override
+ public View getParent() {
+ return parent;
+ }
+
+ @Override
+ public Size getSize() {
+ return new Size(width, height);
+ }
+
+ @Override
+ public ViewSpecification getSpecification() {
+ return null;
+ }
+
+ @Override
+ public ViewState getState() {
+ return null;
+ }
+
+ @Override
+ public View[] getSubviews() {
+ return new View[0];
+ }
+
+ @Override
+ public View getView() {
+ return this;
+ }
+
+ @Override
+ public Viewer getViewManager() {
+ return Toolkit.getViewer();
+ }
+
+ @Override
+ public Feedback getFeedbackManager() {
+ return Toolkit.getFeedbackManager();
+ }
+
+ @Override
+ public Workspace getWorkspace() {
+ return null;
+ }
+
+ @Override
+ public boolean hasFocus() {
+ return getViewManager().hasFocus(getView());
+ }
+
+ @Override
+ public View identify(final Location location) {
+ return this;
+ }
+
+ @Override
+ public void invalidateContent() {
+ }
+
+ @Override
+ public void invalidateLayout() {
+ }
+
+ @Override
+ public void keyPressed(final KeyboardAction key) {
+ if (key.getKeyCode() == KeyEvent.VK_ENTER) {
+ executeAction();
+ }
+ }
+
+ @Override
+ public void keyReleased(final KeyboardAction action) {
+ }
+
+ @Override
+ public void keyTyped(final KeyboardAction action) {
+ }
+
+ @Override
+ public void layout() {
+ }
+
+ @Override
+ public void limitBoundsWithin(final Size size) {
+ }
+
+ @Override
+ public void markDamaged() {
+ markDamaged(getView().getBounds());
+ }
+
+ @Override
+ public void markDamaged(final Bounds bounds) {
+ if (parent == null) {
+ getViewManager().markDamaged(bounds);
+ } else {
+ final Location pos = parent.getLocation();
+ bounds.translate(pos.getX(), pos.getY());
+ parent.markDamaged(bounds);
+ }
+ }
+
+ @Override
+ public void mouseDown(final Click click) {
+ final View target = getParent().getView();
+ if (action.disabled(target).isAllowed()) {
+ markDamaged();
+ getViewManager().saveCurrentFieldEntry();
+ // action.execute(target.getWorkspace(), target, getLocation());
+ }
+ final boolean vetoed = action.disabled(target).isVetoed();
+ if (!vetoed) {
+ isPressed = true;
+ markDamaged();
+ }
+ }
+
+ @Override
+ public void mouseUp(final Click click) {
+ final View target = getParent().getView();
+ final boolean vetoed = action.disabled(target).isVetoed();
+ if (!vetoed) {
+ isPressed = false;
+ markDamaged();
+ }
+ }
+
+ @Override
+ public void mouseMoved(final Location location) {
+ }
+
+ @Override
+ public void objectActionResult(final ObjectAdapter result, final Placement placement) {
+ }
+
+ @Override
+ public View pickupContent(final Location location) {
+ return null;
+ }
+
+ @Override
+ public View pickupView(final Location location) {
+ return null;
+ }
+
+ @Override
+ public void print(final Canvas canvas) {
+ }
+
+ @Override
+ public void refresh() {
+ }
+
+ @Override
+ public void removeView(final View view) {
+ }
+
+ @Override
+ public void replaceView(final View toReplace, final View replacement) {
+ }
+
+ @Override
+ public void secondClick(final Click click) {
+ }
+
+ @Override
+ public void setBounds(final Bounds bounds) {
+ }
+
+ @Override
+ public void setFocusManager(final FocusManager focusManager) {
+ }
+
+ public void setLayout(final Layout layout) {
+ }
+
+ @Override
+ public void setLocation(final Location point) {
+ x = point.getX();
+ y = point.getY();
+ }
+
+ @Override
+ public void setParent(final View view) {
+ }
+
+ public void setMaximumSize(final Size size) {
+ }
+
+ @Override
+ public void setSize(final Size size) {
+ width = size.getWidth();
+ height = size.getHeight();
+ }
+
+ @Override
+ public void setView(final View view) {
+ }
+
+ @Override
+ public View subviewFor(final Location location) {
+ return null;
+ }
+
+ @Override
+ public void thirdClick(final Click click) {
+ }
+
+ @Override
+ public void update(final ObjectAdapter object) {
+ }
+
+ @Override
+ public void updateView() {
+ }
+
+ @Override
+ public ViewAreaType viewAreaType(final Location mouseLocation) {
+ return null;
+ }
+
+ @Override
+ public void viewMenuOptions(final UserActionSet menuOptions) {
+ }
+
+ @Override
+ public void loadOptions(final Options viewOptions) {
+ }
+
+ @Override
+ public void saveOptions(final Options viewOptions) {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/Button.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/Button.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/Button.java
new file mode 100644
index 0000000..80a48a7
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/Button.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.control;
+
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.ButtonAction;
+import org.apache.isis.viewer.dnd.view.View;
+
+public class Button extends AbstractControlView {
+ private static ButtonRender buttonRender;
+
+ public static void setButtonRender(final ButtonRender buttonRender) {
+ Button.buttonRender = buttonRender;
+ }
+
+ public Button(final ButtonAction action, final View target) {
+ super(action, target);
+ }
+
+ @Override
+ public boolean containsFocus() {
+ return hasFocus();
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ final View target = getParent();
+ final String text = action.getName(target);
+ final boolean isDisabled = action.disabled(target).isVetoed();
+ final boolean isDefault = ((ButtonAction) action).isDefault();
+ buttonRender.draw(canvas, getSize(), isDisabled, isDefault, hasFocus(), isOver(), isPressed(), text);
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ final String text = action.getName(getView());
+ return buttonRender.getMaximumSize(text);
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/ButtonRender.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/ButtonRender.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/ButtonRender.java
new file mode 100644
index 0000000..8407cd7
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/ButtonRender.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.control;
+
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Size;
+
+public interface ButtonRender {
+
+ void draw(Canvas canvas, Size size, boolean isDisabled, boolean isDefault, boolean hasFocus, boolean isOver, boolean isPressed, String text);
+
+ Size getMaximumSize(String text);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/CancelAction.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/CancelAction.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/CancelAction.java
new file mode 100644
index 0000000..a8700d1
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/control/CancelAction.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.control;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+
+public class CancelAction extends AbstractButtonAction {
+ private static final Logger LOG = Logger.getLogger(CancelAction.class);
+
+ public CancelAction() {
+ super("Cancel");
+ }
+
+ @Override
+ public void execute(final Workspace workspace, final View view, final Location at) {
+ LOG.debug("cancel pressed");
+ view.dispose();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugAdapter.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugAdapter.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugAdapter.java
new file mode 100644
index 0000000..2ddbe6a
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugAdapter.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.util.Dump;
+
+public class DebugAdapter implements DebuggableWithTitle {
+ private final ObjectAdapter object;
+
+ public DebugAdapter(final ObjectAdapter object) {
+ this.object = object;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ dumpObject(object, debug);
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Adapter";
+ }
+
+ private void dumpObject(final ObjectAdapter object, final DebugBuilder info) {
+ if (object != null) {
+ Dump.adapter(object, info);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugBorder.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugBorder.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugBorder.java
new file mode 100644
index 0000000..f694b6a
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugBorder.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Text;
+import org.apache.isis.viewer.dnd.view.Click;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.base.AbstractBorder;
+
+public class DebugBorder extends AbstractBorder {
+ public DebugBorder(final View wrappedView) {
+ super(wrappedView);
+
+ bottom = Toolkit.getText(ColorsAndFonts.TEXT_DEBUG).getTextHeight();
+ }
+
+ @Override
+ protected void debugDetails(final DebugBuilder debug) {
+ debug.append("DebugBorder");
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ final String debug = getView() + " " + getState();
+ final Text text = Toolkit.getText(ColorsAndFonts.TEXT_DEBUG);
+ final int baseline = wrappedView.getSize().getHeight() + text.getAscent();
+ final Color color = Toolkit.getColor(ColorsAndFonts.COLOR_DEBUG_BASELINE);
+ canvas.drawText(debug, 0, baseline, color, text);
+
+ super.draw(canvas);
+ }
+
+ @Override
+ public String toString() {
+ return wrappedView.toString() + "/DebugBorder";
+ }
+
+ @Override
+ public void firstClick(final Click click) {
+ new DebugOption().execute(getWorkspace(), getView(), click.getLocation());
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugContent.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugContent.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugContent.java
new file mode 100644
index 0000000..40b3b38
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugContent.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.View;
+
+public class DebugContent implements DebuggableWithTitle {
+ private final View view;
+
+ public DebugContent(final View display) {
+ this.view = display;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ final Content content = view.getContent();
+ if (content != null) {
+ String type = content.getClass().getName();
+ type = type.substring(type.lastIndexOf('.') + 1);
+ debug.appendln("Content", type);
+
+ debug.indent();
+
+ content.debugDetails(debug);
+
+ debug.appendln("Icon name", content.getIconName());
+ debug.appendln("Icon ", content.getIconPicture(32));
+ debug.appendln("Window title", content.windowTitle());
+
+ debug.appendln("Object", content.isObject());
+ debug.appendln("Collection", content.isCollection());
+
+ debug.appendln("Text Parseable", content.isTextParseable());
+
+ debug.unindent();
+ } else {
+ debug.appendln("Content", "none");
+ }
+ debug.blankLine();
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Content";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawing.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawing.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawing.java
new file mode 100644
index 0000000..1b5133a
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawing.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.viewer.dnd.drawing.Bounds;
+import org.apache.isis.viewer.dnd.drawing.DebugCanvas;
+import org.apache.isis.viewer.dnd.view.View;
+
+public class DebugDrawing implements DebuggableWithTitle {
+ private final View view;
+
+ public DebugDrawing(final View display) {
+ this.view = display;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ view.draw(new DebugCanvas(debug, new Bounds(view.getBounds())));
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Drawing";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawingAbsolute.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawingAbsolute.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawingAbsolute.java
new file mode 100644
index 0000000..cf2c62e
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDrawingAbsolute.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.viewer.dnd.drawing.Bounds;
+import org.apache.isis.viewer.dnd.drawing.DebugCanvasAbsolute;
+import org.apache.isis.viewer.dnd.view.View;
+
+public class DebugDrawingAbsolute implements DebuggableWithTitle {
+ private final View view;
+
+ public DebugDrawingAbsolute(final View display) {
+ this.view = display;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ view.draw(new DebugCanvasAbsolute(debug, new Bounds(view.getAbsoluteLocation(), view.getSize())));
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Drawing (Absolute)";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDumpSnapshotOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDumpSnapshotOption.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDumpSnapshotOption.java
new file mode 100644
index 0000000..62ff97e
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugDumpSnapshotOption.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import static org.apache.isis.core.commons.lang.CastUtils.enumerationOver;
+
+import java.util.Enumeration;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.metamodel.consent.Allow;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.runtime.logging.SnapshotAppender;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+/**
+ * Display debug window
+ */
+public class DebugDumpSnapshotOption extends UserActionAbstract {
+ public DebugDumpSnapshotOption() {
+ super("Dump log snapshot", ActionType.DEBUG);
+ }
+
+ @Override
+ public Consent disabled(final View component) {
+ final Enumeration<Logger> enumeration = enumerationOver(Logger.getRootLogger().getAllAppenders(), Logger.class);
+ while (enumeration.hasMoreElements()) {
+ final Appender appender = (Appender) enumeration.nextElement();
+ if (appender instanceof SnapshotAppender) {
+ return Allow.DEFAULT;
+ }
+ }
+ // TODO: move logic into Facet
+ return new Veto("No available snapshot appender");
+ }
+
+ @Override
+ public void execute(final Workspace workspace, final View view, final Location at) {
+ final Enumeration<Logger> enumeration = enumerationOver(Logger.getRootLogger().getAllAppenders(), Logger.class);
+ while (enumeration.hasMoreElements()) {
+ final Appender appender = (Appender) enumeration.nextElement();
+ if (appender instanceof SnapshotAppender) {
+ ((SnapshotAppender) appender).forceSnapshot();
+ }
+ }
+ }
+
+ @Override
+ public String getDescription(final View view) {
+ return "Force a snapshot of the log";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectGraph.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectGraph.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectGraph.java
new file mode 100644
index 0000000..52f3d6f
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectGraph.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.util.Dump;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+
+public class DebugObjectGraph implements DebuggableWithTitle {
+ private final ObjectAdapter object;
+
+ public DebugObjectGraph(final ObjectAdapter object) {
+ this.object = object;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ dumpGraph(object, debug);
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Object Graph";
+ }
+
+ private void dumpGraph(final ObjectAdapter object, final DebugBuilder info) {
+ if (object != null) {
+ Dump.graph(object, IsisContext.getAuthenticationSession(), info);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectSpecification.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectSpecification.java
new file mode 100644
index 0000000..6e433e6
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugObjectSpecification.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.util.Dump;
+
+public class DebugObjectSpecification implements DebuggableWithTitle {
+ private final ObjectSpecification specification;
+
+ public DebugObjectSpecification(final ObjectAdapter object) {
+ this.specification = object.getSpecification();
+ }
+
+ public DebugObjectSpecification(final ObjectSpecification object) {
+ this.specification = object;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ if (specification == null) {
+ debug.appendln("no specfication");
+ } else {
+ Dump.specification(specification, debug);
+ }
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Object Specification";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOption.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOption.java
new file mode 100644
index 0000000..20bb5cc
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOption.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.runtime.userprofile.PerspectiveEntry;
+import org.apache.isis.runtimes.dflt.runtime.userprofile.UserProfilesDebugUtil;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.service.PerspectiveContent;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+/**
+ * Display debug window
+ */
+public class DebugOption extends UserActionAbstract {
+ public DebugOption() {
+ super("Debug...", ActionType.DEBUG);
+ }
+
+ @Override
+ public void execute(final Workspace workspace, final View view, final Location at) {
+ final Content content = view.getContent();
+ final ObjectAdapter object = content == null ? null : content.getAdapter();
+
+ final List<DebuggableWithTitle> debug = Lists.newArrayList();
+ if (content instanceof PerspectiveContent) {
+ final PerspectiveEntry perspectiveEntry = ((PerspectiveContent) content).getPerspective();
+ debug.add(UserProfilesDebugUtil.asDebuggableWithTitle(perspectiveEntry));
+ } else {
+ debug.add(new DebugObjectSpecification(content.getSpecification()));
+ }
+ if (object != null) {
+ debug.add(new DebugAdapter(object));
+ debug.add(new DebugObjectGraph(object));
+ }
+
+ debug.add(new DebugViewStructure(view));
+ debug.add(new DebugContent(view));
+ debug.add(new DebugDrawing(view));
+ debug.add(new DebugDrawingAbsolute(view));
+
+ final DebuggableWithTitle[] info = debug.toArray(new DebuggableWithTitle[debug.size()]);
+ at.add(50, 6);
+ // at.getX() + 50, at.getY() + 6
+ Toolkit.getViewer().showDebugFrame(info, at);
+ }
+
+ @Override
+ public String getDescription(final View view) {
+ return "Open debug window about " + view;
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOutput.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOutput.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOutput.java
new file mode 100644
index 0000000..c58a96f
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugOutput.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import java.awt.FileDialog;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.PrintJob;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.isis.core.commons.debug.DebugString;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public class DebugOutput {
+ private static final DateFormat FORMAT = new SimpleDateFormat("yyyyMMdd-HHmmss-SSS");
+ private static final Font TEXT_FONT = new Font("SansSerif", Font.PLAIN, 10);
+ private static final Font TITLE_FONT = new Font("SansSerif", Font.BOLD, 12);
+
+ public static void print(final String title, final String text) {
+ final Frame parent = new Frame();
+ final PrintJob job = Toolkit.getDefaultToolkit().getPrintJob(parent, "Print " + title, new Properties());
+
+ if (job != null) {
+ final Graphics graphic = job.getGraphics();
+ // Dimension pageSize = job.getPageDimension();
+
+ if (graphic != null) {
+ graphic.translate(10, 10);
+ final int x = 50;
+ int y = 50;
+
+ graphic.setFont(TITLE_FONT);
+
+ final int height = graphic.getFontMetrics().getAscent();
+ final int width = graphic.getFontMetrics().stringWidth(title);
+ graphic.drawRect(x - 10, y - 10 - height, width + 20, height + 20);
+
+ graphic.drawString(title, x, y);
+
+ y += graphic.getFontMetrics().getHeight();
+ y += 20;
+
+ graphic.setFont(TEXT_FONT);
+ final StringTokenizer tk = new StringTokenizer(text, "\n\r");
+ while (tk.hasMoreTokens()) {
+ final String line = tk.nextToken();
+ graphic.drawString(line, x, y);
+ y += graphic.getFontMetrics().getHeight();
+ }
+
+ graphic.dispose();
+ }
+
+ job.end();
+ }
+ parent.dispose();
+ }
+
+ /*
+ *
+ *
+ * Frame frame = new Frame(); PrintJob job =
+ * Toolkit.getDefaultToolkit().getPrintJob(frame, "Print object", null);
+ *
+ * if (job != null) { Graphics pg = job.getGraphics(); Dimension pageSize =
+ * job.getPageDimension();
+ *
+ * if (pg != null) { pg.translate(LEFT, HEIGHT); pg.drawRect(0, 0,
+ * pageSize.width - LEFT - 1, pageSize.height - HEIGHT - 1); view.print(new
+ * PrintCanvas(pg, view)); pg.dispose(); }
+ *
+ * job.end(); } frame.dispose();
+ */
+
+ public static void saveToClipboard(final String text) {
+ final Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+ final StringSelection ss = new StringSelection(text);
+ cb.setContents(ss, ss);
+ }
+
+ public static void saveToFile(final DebuggableWithTitle object) {
+ final String dateStamp = FORMAT.format(new Date());
+ final String fileName = object.getClass().getName() + "-" + dateStamp + ".txt";
+ final DebugString text = new DebugString();
+ object.debugData(text);
+ final String title = object.debugTitle();
+
+ saveToFile(new File(fileName), title, text.toString());
+ }
+
+ public static void saveToFile(final File file, final String title, final String text) {
+ try {
+ final PrintWriter writer = new PrintWriter(new FileWriter(file));
+ writer.println(title);
+ writer.println();
+ writer.println(text.toString());
+ writer.close();
+ } catch (final IOException e) {
+ throw new IsisException(e);
+ }
+ }
+
+ public static void saveToFile(final String saveDialogTitle, final String title, final String text) {
+ final Frame parent = new Frame();
+
+ final FileDialog dialog = new FileDialog(parent, saveDialogTitle, FileDialog.SAVE);
+ dialog.setVisible(true);
+ final String file = dialog.getFile();
+ final String dir = dialog.getDirectory();
+
+ parent.dispose();
+
+ saveToFile(new File(dir, file), title, text);
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugView.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugView.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugView.java
new file mode 100644
index 0000000..66b8446
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugView.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.util.Dump;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.drawing.Bounds;
+import org.apache.isis.viewer.dnd.drawing.DebugCanvas;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.ObjectContent;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.collection.CollectionContent;
+
+public class DebugView implements DebuggableWithTitle {
+ private final View view;
+
+ public DebugView(final View display) {
+ this.view = display;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ debug.append(view.getView());
+ debug.blankLine();
+ debug.blankLine();
+
+ // display details
+ debug.appendTitle("VIEW");
+
+ view.debug(debug);
+ debug.appendln();
+
+ // content
+ final Content content = view.getContent();
+ debug.appendTitle("CONTENT");
+ if (content != null) {
+ String type = content.getClass().getName();
+ type = type.substring(type.lastIndexOf('.') + 1);
+ debug.appendln("Content", type);
+ content.debugDetails(debug);
+
+ debug.indent();
+ debug.appendln("Icon name", content.getIconName());
+ debug.appendln("Icon ", content.getIconPicture(32));
+ debug.appendln("Window title", content.windowTitle());
+ debug.appendln("Persistable", content.isPersistable());
+ debug.appendln("Object", content.isObject());
+ debug.appendln("Collection", content.isCollection());
+
+ debug.appendln("Parseable", content.isTextParseable());
+ debug.unindent();
+ } else {
+ debug.appendln("Content", "none");
+ }
+ debug.blankLine();
+
+ if (content instanceof ObjectContent) {
+ final ObjectAdapter object = ((ObjectContent) content).getObject();
+ dumpObject(object, debug);
+ debug.blankLine();
+ dumpSpecification(object, debug);
+ debug.blankLine();
+ dumpGraph(object, debug);
+
+ } else if (content instanceof CollectionContent) {
+ final ObjectAdapter collection = ((CollectionContent) content).getCollection();
+ debug.blankLine();
+ dumpObject(collection, debug);
+ dumpSpecification(collection, debug);
+ debug.blankLine();
+ dumpGraph(collection, debug);
+ }
+
+ debug.append("\n\nDRAWING\n");
+ debug.append("------\n");
+ view.draw(new DebugCanvas(debug, new Bounds(view.getBounds())));
+ }
+
+ @Override
+ public String debugTitle() {
+ return "Debug: " + view + view == null ? "" : ("/" + view.getContent());
+ }
+
+ public void dumpGraph(final ObjectAdapter object, final DebugBuilder info) {
+ if (object != null) {
+ info.appendTitle("GRAPH");
+ Dump.graph(object, IsisContext.getAuthenticationSession(), info);
+ }
+ }
+
+ public void dumpObject(final ObjectAdapter object, final DebugBuilder info) {
+ if (object != null) {
+ info.appendTitle("OBJECT");
+ Dump.adapter(object, info);
+ }
+ }
+
+ private void dumpSpecification(final ObjectAdapter object, final DebugBuilder info) {
+ if (object != null) {
+ info.appendTitle("SPECIFICATION");
+ Dump.specification(object, info);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugViewStructure.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugViewStructure.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugViewStructure.java
new file mode 100644
index 0000000..dd7ea75
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/DebugViewStructure.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.viewer.dnd.view.View;
+
+public class DebugViewStructure implements DebuggableWithTitle {
+ private final View view;
+
+ public DebugViewStructure(final View display) {
+ this.view = display;
+ }
+
+ @Override
+ public void debugData(final DebugBuilder debug) {
+ view.debug(debug);
+ }
+
+ @Override
+ public String debugTitle() {
+ return "View Structure";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/LoggingOptions.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/LoggingOptions.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/LoggingOptions.java
new file mode 100644
index 0000000..6ec4102
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/debug/LoggingOptions.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.debug;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.ConsentAbstract;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.MenuOptions;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public class LoggingOptions implements MenuOptions {
+
+ @Override
+ public void menuOptions(final UserActionSet options) {
+ options.add(loggingOption("Off", Level.OFF));
+ options.add(loggingOption("Error", Level.ERROR));
+ options.add(loggingOption("Warn", Level.WARN));
+ options.add(loggingOption("Info", Level.INFO));
+ options.add(loggingOption("Debug", Level.DEBUG));
+
+ options.add(new DebugDumpSnapshotOption());
+ }
+
+ private UserActionAbstract loggingOption(final String name, final Level level) {
+ return new UserActionAbstract("Log level " + level, ActionType.DEBUG) {
+ @Override
+ public Consent disabled(final View component) {
+ return ConsentAbstract.allowIf(LogManager.getRootLogger().getLevel() != level);
+ }
+
+ @Override
+ public void execute(final Workspace workspace, final View view, final Location at) {
+ LogManager.getRootLogger().setLevel(level);
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToManyAssociationOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToManyAssociationOption.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToManyAssociationOption.java
new file mode 100644
index 0000000..530e19d
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToManyAssociationOption.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public class ClearOneToManyAssociationOption extends UserActionAbstract {
+
+ public ClearOneToManyAssociationOption() {
+ super("Clear association");
+ }
+
+ @Override
+ public Consent disabled(final View view) {
+ final OneToManyFieldElement content = (OneToManyFieldElement) view.getContent();
+ return content.canClear();
+ }
+
+ @Override
+ public void execute(final Workspace frame, final View view, final Location at) {
+ final OneToManyFieldElement content = (OneToManyFieldElement) view.getContent();
+ content.clear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToOneAssociationOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToOneAssociationOption.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToOneAssociationOption.java
new file mode 100644
index 0000000..44f0009
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ClearOneToOneAssociationOption.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public class ClearOneToOneAssociationOption extends UserActionAbstract {
+ public ClearOneToOneAssociationOption() {
+ super("Clear association");
+ }
+
+ @Override
+ public Consent disabled(final View view) {
+ final OneToOneField content = ((OneToOneField) view.getContent());
+ return content.canClear();
+ }
+
+ @Override
+ public void execute(final Workspace frame, final View view, final Location at) {
+ final OneToOneField content = ((OneToOneField) view.getContent());
+ content.clear();
+ view.getParent().invalidateContent();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ObjectField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ObjectField.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ObjectField.java
new file mode 100644
index 0000000..f1ddb42
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/ObjectField.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+
+final class ObjectField {
+ private final ObjectAssociation field;
+ private final ObjectAdapter parent;
+
+ ObjectField(final ObjectAdapter parent, final ObjectAssociation field) {
+ this.parent = parent;
+ this.field = field;
+ }
+
+ public void debugDetails(final DebugBuilder debug) {
+ debug.appendln("field", getObjectAssociation());
+ debug.appendln("name", getName());
+ debug.appendln("specification", getSpecification());
+ debug.appendln("parent", parent);
+ }
+
+ public String getDescription() {
+ return field.getDescription();
+ }
+
+ public String getHelp() {
+ return field.getHelp();
+ }
+
+ public ObjectAssociation getObjectAssociation() {
+ return field;
+ }
+
+ public final String getName() {
+ return field.getName();
+ }
+
+ public ObjectAdapter getParent() {
+ return parent;
+ }
+
+ public ObjectSpecification getSpecification() {
+ return field.getSpecification();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyField.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyField.java
new file mode 100644
index 0000000..b49375b
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyField.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.viewer.dnd.view.collection.CollectionContent;
+import org.apache.isis.viewer.dnd.view.content.FieldContent;
+
+public interface OneToManyField extends FieldContent, CollectionContent {
+ OneToManyAssociation getOneToManyAssociation();
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElement.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElement.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElement.java
new file mode 100644
index 0000000..15db170
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElement.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.isis.viewer.dnd.view.ObjectContent;
+import org.apache.isis.viewer.dnd.view.content.FieldContent;
+
+public interface OneToManyFieldElement extends FieldContent, ObjectContent {
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElementImpl.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElementImpl.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElementImpl.java
new file mode 100644
index 0000000..118b4f7
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldElementImpl.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.content.AbstractObjectContent;
+
+public class OneToManyFieldElementImpl extends AbstractObjectContent implements OneToManyFieldElement {
+ private static final Logger LOG = Logger.getLogger(OneToManyFieldElementImpl.class);
+ private final ObjectAdapter element;
+ private final ObjectField field;
+
+ public OneToManyFieldElementImpl(final ObjectAdapter parent, final ObjectAdapter element, final OneToManyAssociation association) {
+ field = new ObjectField(parent, association);
+ this.element = element;
+ }
+
+ @Override
+ public Consent canClear() {
+ final ObjectAdapter parentObject = getParent();
+ final OneToManyAssociation association = getOneToManyAssociation();
+ final ObjectAdapter associatedObject = getObject();
+
+ final Consent isEditable = isEditable();
+ if (isEditable.isVetoed()) {
+ return isEditable;
+ }
+
+ final Consent consent = association.isValidToRemove(parentObject, associatedObject);
+ if (consent.isAllowed()) {
+ consent.setDescription("Clear the association to this object from '" + parentObject.titleString() + "'");
+ }
+ return consent;
+ }
+
+ @Override
+ public Consent isEditable() {
+ return getField().isUsable(IsisContext.getAuthenticationSession(), getParent(), where);
+ }
+
+ @Override
+ public Consent canSet(final ObjectAdapter dragSource) {
+ return Veto.DEFAULT;
+ }
+
+ @Override
+ public void clear() {
+ final ObjectAdapter parentObject = getParent();
+ final OneToManyAssociation association = getOneToManyAssociation();
+ LOG.debug("remove " + element + " from " + parentObject);
+ association.removeElement(parentObject, element);
+ }
+
+ @Override
+ public void debugDetails(final DebugBuilder debug) {
+ field.debugDetails(debug);
+ debug.appendln("element", element);
+ }
+
+ @Override
+ public String getFieldName() {
+ return field.getName();
+ }
+
+ @Override
+ public ObjectAssociation getField() {
+ return field.getObjectAssociation();
+ }
+
+ @Override
+ public ObjectAdapter getAdapter() {
+ return element;
+ }
+
+ @Override
+ public ObjectAdapter getObject() {
+ return element;
+ }
+
+ @Override
+ public ObjectAdapter[] getOptions() {
+ return null;
+ }
+
+ private OneToManyAssociation getOneToManyAssociation() {
+ return (OneToManyAssociation) field.getObjectAssociation();
+ }
+
+ @Override
+ public ObjectAdapter getParent() {
+ return field.getParent();
+ }
+
+ @Override
+ public ObjectSpecification getSpecification() {
+ return field.getSpecification();
+ }
+
+ @Override
+ public boolean isMandatory() {
+ return false;
+ }
+
+ @Override
+ public boolean isObject() {
+ return true;
+ }
+
+ @Override
+ public boolean isOptionEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return false;
+ }
+
+ @Override
+ public void contentMenuOptions(final UserActionSet options) {
+ // ObjectOption.menuOptions(element, options);
+ super.contentMenuOptions(options);
+ options.add(new ClearOneToManyAssociationOption());
+ }
+
+ @Override
+ public void setObject(final ObjectAdapter object) {
+ /*
+ * ObjectAdapter parentObject = getParent();
+ * OneToManyAssociationSpecification association =
+ * getOneToManyAssociation(); ObjectAdapter associatedObject =
+ * getObject(); LOG.debug("remove " + associatedObject + " from " +
+ * parentObject); association.clearAssociation(parentObject,
+ * associatedObject);
+ */
+
+ }
+
+ @Override
+ public String title() {
+ return element.titleString();
+ }
+
+ @Override
+ public String toString() {
+ return getObject() + "/" + field.getObjectAssociation();
+ }
+
+ @Override
+ public String windowTitle() {
+ return field.getName() + " element" + " for " + field.getParent().titleString();
+ }
+
+ @Override
+ public String getId() {
+ return getOneToManyAssociation().getName();
+ }
+
+ @Override
+ public String getDescription() {
+ return field.getName() + ": " + getOneToManyAssociation().getDescription();
+ }
+
+ @Override
+ public String getHelp() {
+ return getOneToManyAssociation().getHelp();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldImpl.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldImpl.java b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldImpl.java
new file mode 100644
index 0000000..1fdb9ab
--- /dev/null
+++ b/component/viewer/dnd/impl/src/main/java/org/apache/isis/viewer/dnd/view/field/OneToManyFieldImpl.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.view.field;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.drawing.Image;
+import org.apache.isis.viewer.dnd.drawing.ImageFactory;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.collection.AbstractCollectionContent;
+
+public class OneToManyFieldImpl extends AbstractCollectionContent implements OneToManyField {
+
+ // REVIEW: should provide this rendering context, rather than hardcoding.
+ // the net effect currently is that class members annotated with
+ // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+ // be hidden/disabled, but will be visible/enabled (perhaps incorrectly)
+ // for any other value for Where
+ private final Where where = Where.ANYWHERE;
+
+ private final ObjectAdapter collection;
+ private final ObjectField field;
+
+ public OneToManyFieldImpl(final ObjectAdapter parent, final ObjectAdapter object, final OneToManyAssociation association) {
+ field = new ObjectField(parent, association);
+ this.collection = object;
+ }
+
+ @Override
+ public Consent canDrop(final Content sourceContent) {
+ if (sourceContent.getAdapter() instanceof ObjectAdapter) {
+ final ObjectAdapter sourceAdapter = sourceContent.getAdapter();
+ final ObjectAdapter parentAdapter = field.getParent();
+
+ final ObjectAdapter collection = getAdapter();
+ if (collection == null) {
+ // TODO: move logic into Facet
+ return new Veto("Collection not set up; can't add elements to a non-existant collection");
+ }
+
+ final Consent usableInState = getOneToManyAssociation().isUsable(IsisContext.getAuthenticationSession(), parentAdapter, where);
+ if (usableInState.isVetoed()) {
+ return usableInState;
+ }
+
+ final ObjectSpecification specification = sourceAdapter.getSpecification();
+ final ObjectSpecification elementSpecification = getElementSpecification();
+ if (!specification.isOfType(elementSpecification)) {
+ // TODO: move logic into Facet
+ return new Veto(String.format("Only objects of type %s are allowed in this collection", elementSpecification.getSingularName()));
+ }
+ if (parentAdapter.representsPersistent() && sourceAdapter.isTransient()) {
+ // TODO: move logic into Facet
+ return new Veto("Can't set field in persistent object with reference to non-persistent object");
+ }
+ return getOneToManyAssociation().isValidToAdd(parentAdapter, sourceAdapter);
+ } else {
+ return Veto.DEFAULT;
+ }
+ }
+
+ public Consent canSet(final ObjectAdapter dragSource) {
+ return Veto.DEFAULT;
+ }
+
+ @Override
+ public void contentMenuOptions(final UserActionSet options) {
+ super.contentMenuOptions(options);
+ // OptionFactory.addCreateOptions(getOneToManyAssociation().getSpecification(),
+ // options);
+ }
+
+ @Override
+ public void debugDetails(final DebugBuilder debug) {
+ field.debugDetails(debug);
+ debug.appendln("collection", collection);
+ super.debugDetails(debug);
+ }
+
+ @Override
+ public ObjectAdapter drop(final Content sourceContent) {
+ final ObjectAdapter object = sourceContent.getAdapter();
+ final ObjectAdapter parent = field.getParent();
+ final Consent perm = canDrop(sourceContent);
+ if (perm.isAllowed()) {
+ getOneToManyAssociation().addElement(parent, object);
+ }
+ return null;
+ }
+
+ @Override
+ public ObjectAdapter getCollection() {
+ return collection;
+ }
+
+ @Override
+ public String getDescription() {
+ final String name = getFieldName();
+ String type = getField().getSpecification().getSingularName();
+ type = name.indexOf(type) == -1 ? " (" + type + ")" : "";
+ final String description = getOneToManyAssociation().getDescription();
+ return name + type + " " + description;
+ }
+
+ @Override
+ public ObjectAssociation getField() {
+ return field.getObjectAssociation();
+ }
+
+ @Override
+ public String getFieldName() {
+ return field.getName();
+ }
+
+ @Override
+ public String getHelp() {
+ return getOneToManyAssociation().getHelp();
+ }
+
+ @Override
+ public String getIconName() {
+ return null;
+ // return "internal-collection";
+ }
+
+ @Override
+ public Image getIconPicture(final int iconHeight) {
+ final ObjectSpecification specification = getOneToManyAssociation().getSpecification();
+ Image icon = ImageFactory.getInstance().loadIcon(specification, iconHeight, null);
+ if (icon == null) {
+ icon = ImageFactory.getInstance().loadDefaultIcon(iconHeight, null);
+ }
+ return icon;
+ }
+
+ @Override
+ public String getId() {
+ return getOneToManyAssociation().getId();
+ }
+
+ @Override
+ public ObjectAdapter getAdapter() {
+ return collection;
+ }
+
+ @Override
+ public OneToManyAssociation getOneToManyAssociation() {
+ return (OneToManyAssociation) field.getObjectAssociation();
+ }
+
+ @Override
+ public ObjectAdapter getParent() {
+ return field.getParent();
+ }
+
+ @Override
+ public ObjectSpecification getSpecification() {
+ return field.getSpecification();
+ }
+
+ @Override
+ public Consent isEditable() {
+ return getField().isUsable(IsisContext.getAuthenticationSession(), getParent(), where);
+ }
+
+ @Override
+ public boolean isMandatory() {
+ return getOneToManyAssociation().isMandatory();
+ }
+
+ @Override
+ public boolean isTransient() {
+ return false;
+ }
+
+ public void setObject(final ObjectAdapter object) {
+ throw new IsisException("Invalid call");
+ }
+
+ @Override
+ public final String title() {
+ return field.getName();
+ }
+
+ @Override
+ public String toString() {
+ return collection + "/" + field.getObjectAssociation();
+ }
+
+ @Override
+ public String windowTitle() {
+ return title() + " for " + field.getParent().titleString();
+ }
+
+}