Add comment anchor for more directed code browsing

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@948601 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2010-05-26 21:43:54 +00:00
parent 5fa827bcce
commit e4162075cf
10 changed files with 91 additions and 37 deletions

View File

@ -182,7 +182,7 @@ public final class BuyBookPage extends JPanel {
JButton searchButton = new JButton("Search", Images.START); JButton searchButton = new JButton("Search", Images.START);
searchButton.setHorizontalTextPosition(SwingConstants.LEADING); searchButton.setHorizontalTextPosition(SwingConstants.LEADING);
ShowCodeAction showCode = Demo.getInstance().new ShowCodeAction(); ShowCodeAction showCode = Demo.getInstance().new ShowCodeAction();
showCode.setPage("Derived identity", "openbook/domain/LineItem.java.html#example.compound-derived-identity"); showCode.setPage("Dynamic Query", "openbook/server/OpenBookServiceImpl.java.html#buildQuery");
JButton viewCodeButton = new JButton(showCode); JButton viewCodeButton = new JButton(showCode);
JPanel buttonPanel = new JPanel(); JPanel buttonPanel = new JPanel();

View File

@ -29,6 +29,7 @@ import javax.persistence.OneToOne;
import javax.persistence.Version; import javax.persistence.Version;
/** /**
* <A name="class"/>
* An immutable persistent entity represents a Book. * An immutable persistent entity represents a Book.
* <br> * <br>
* The mutable properties of the book such as number of items in stock etc. * The mutable properties of the book such as number of items in stock etc.
@ -62,6 +63,11 @@ public class Book implements Serializable {
orphanRemoval=true) orphanRemoval=true)
private Inventory inventory; private Inventory inventory;
/**
* <A name="authors">
* A many-to-many <em>eager</em> relation.
* By default, many-to-many relations are lazily fetched.
*/
@ManyToMany(fetch=FetchType.EAGER) @ManyToMany(fetch=FetchType.EAGER)
private List<Author> authors; private List<Author> authors;

View File

@ -39,7 +39,7 @@ import javax.persistence.OrderColumn;
@IdClass(LineItem.LineItemId.class) @IdClass(LineItem.LineItemId.class)
public class LineItem implements Serializable { public class LineItem implements Serializable {
/** /**
* <A name="example.compound-derived-identity"> * <A name="order">
* An example of a compound derived identity. * An example of a compound derived identity.
*/ */
@Id @Id

View File

@ -65,6 +65,10 @@ public class PurchaseOrder implements Serializable {
*/ */
public enum Status {PENDING, DELIVERED}; public enum Status {PENDING, DELIVERED};
/**
* <A name="id">
* Persistent Identity is generated by the provider.
*/
@Id @Id
@GeneratedValue @GeneratedValue
private long id; private long id;
@ -72,6 +76,15 @@ public class PurchaseOrder implements Serializable {
@OneToOne(optional=false) @OneToOne(optional=false)
private Customer customer; private Customer customer;
/**
* <A name="items">
* A composite relation.
* All persistence operation on this order are cascaded to its line items.
* Moreover, a line item ceases to exist even in the database if it is no
* more referred to by a order. This is known as <em>orphan delete</em>
* and can be termed as <em>persistent garbage collection</em>.
*
*/
@OneToMany(mappedBy="order", fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true) @OneToMany(mappedBy="order", fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true)
private List<LineItem> items; private List<LineItem> items;
@ -98,6 +111,7 @@ public class PurchaseOrder implements Serializable {
} }
/** /**
* <A name="init"/>
* Construct a new order by transferring the content of the given {@linkplain ShoppingCart}. * Construct a new order by transferring the content of the given {@linkplain ShoppingCart}.
* *
* @param cart a non-null, non-empty Shopping cart * @param cart a non-null, non-empty Shopping cart
@ -141,7 +155,12 @@ public class PurchaseOrder implements Serializable {
return status; return status;
} }
public boolean isDelivered() {
return Status.DELIVERED.equals(status);
}
/** /**
* <A name="setDelivered"/>
* Sets the status of this Purchase Order as delivered. * Sets the status of this Purchase Order as delivered.
* Setting an order status as delivered nullifies the association to Line Items. * Setting an order status as delivered nullifies the association to Line Items.
* Nullifying this association has the important side-effect of Line Item records * Nullifying this association has the important side-effect of Line Item records

View File

@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* <A name="non-persistent"/>
* A non-persistent entity holds the content of a shopping session for a {@linkplain Customer}. * A non-persistent entity holds the content of a shopping session for a {@linkplain Customer}.
* Used to create a persistent PurchaseOrder. * Used to create a persistent PurchaseOrder.
* Books can be added or removed from this cart. * Books can be added or removed from this cart.
@ -30,7 +31,15 @@ import java.util.Map;
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class ShoppingCart implements Serializable { public class ShoppingCart implements Serializable {
/**
* The owner of this cart.
*/
private Customer customer; private Customer customer;
/**
* <A name="items"/>
* The items in the cart and their respective quantity.
*/
private Map<Book, Integer> items; private Map<Book, Integer> items;
/** /**

View File

@ -158,10 +158,13 @@ class OpenBookServiceImpl extends PersistenceService implements OpenBookService
} }
/** /**
* Provide a name and email to login a Customer. * <A name="login">
* Provide a name to login a Customer.
* If such a customer exists, return it. Otherwise creates a new one. * If such a customer exists, return it. Otherwise creates a new one.
* @param name *
* @return * @param name name of an existing or a new Customer
*
* @return a Customer
*/ */
public Customer login(String name) { public Customer login(String name) {
EntityManager em = begin(); EntityManager em = begin();
@ -206,12 +209,20 @@ class OpenBookServiceImpl extends PersistenceService implements OpenBookService
return result; return result;
} }
/**
* <A name="getQuery">
* Gets the string representation of a Criteria Query.
* The string form of a Criteria Query is not specified in JPA specification.
* But OpenJPA produces a readable form that is quite <em>similar</em> to
* equivalent JPQL.
*/
public String getQuery(String title, Double minPrice, Double maxPrice, String author) { public String getQuery(String title, Double minPrice, Double maxPrice, String author) {
CriteriaQuery<Book> q = buildQuery(title, minPrice, maxPrice, author); CriteriaQuery<Book> q = buildQuery(title, minPrice, maxPrice, author);
return q.toString(); return q.toString();
} }
/** /**
* <A name="buildQuery">
* Creates a Query based on the values of the user input form. * Creates a Query based on the values of the user input form.
* The user may or may not have filled a value for each form field * The user may or may not have filled a value for each form field
* and accordingly the query will be different.<br> * and accordingly the query will be different.<br>
@ -222,21 +233,31 @@ class OpenBookServiceImpl extends PersistenceService implements OpenBookService
* introduced in JPA version 2.0. * introduced in JPA version 2.0.
* <br> * <br>
* *
*
* @return a typed query * @return a typed query
*/ */
private CriteriaQuery<Book> buildQuery(String title, private CriteriaQuery<Book> buildQuery(String title, Double minPrice, Double maxPrice, String author) {
Double minPrice, Double maxPrice, // builder generates the Criteria Query as well as all the expressions
String author) {
CriteriaBuilder cb = getUnit().getCriteriaBuilder(); CriteriaBuilder cb = getUnit().getCriteriaBuilder();
// The query declares what type of result it will produce
CriteriaQuery<Book> q = cb.createQuery(Book.class); CriteriaQuery<Book> q = cb.createQuery(Book.class);
// Which type will be searched
Root<Book> book = q.from(Book.class); Root<Book> book = q.from(Book.class);
// of course, the projection term must match the result type declared earlier
q.select(book);
// Builds the predicates conditionally for the filled-in input fields
List<Predicate> predicates = new ArrayList<Predicate>(); List<Predicate> predicates = new ArrayList<Predicate>();
if (title != null && title.trim().length() > 0) { if (!isEmpty(title)) {
Predicate matchTitle = cb.like(book.get(Book_.title), title); Predicate matchTitle = cb.like(book.get(Book_.title), title);
predicates.add(matchTitle); predicates.add(matchTitle);
} }
if (!isEmpty(author)) {
Predicate matchAuthor = cb.like(book.join(Book_.authors).get(Author_.name), "%"+author+"%");
predicates.add(matchAuthor);
}
// for price fields, also the comparison operation changes based on whether
// minimum or maximum price or both have been filled.
if (minPrice != null && maxPrice != null) { if (minPrice != null && maxPrice != null) {
Predicate matchPrice = cb.between(book.get(Book_.price), minPrice, maxPrice); Predicate matchPrice = cb.between(book.get(Book_.price), minPrice, maxPrice);
predicates.add(matchPrice); predicates.add(matchPrice);
@ -247,26 +268,30 @@ class OpenBookServiceImpl extends PersistenceService implements OpenBookService
Predicate matchPrice = cb.le(book.get(Book_.price), maxPrice); Predicate matchPrice = cb.le(book.get(Book_.price), maxPrice);
predicates.add(matchPrice); predicates.add(matchPrice);
} }
if (author != null && author.trim().length() > 0) { // Sets the evaluation criteria
Predicate matchAuthor = cb.like(book.join(Book_.authors).get(Author_.name), "%"+author+"%");
predicates.add(matchAuthor);
}
q.select(book);
if (!predicates.isEmpty()) if (!predicates.isEmpty())
q.where(predicates.toArray(new Predicate[predicates.size()])); q.where(predicates.toArray(new Predicate[predicates.size()]));
return q; return q;
} }
boolean isEmpty(String s) {
return s == null || s.trim().isEmpty();
}
/** /**
* Deliver pending orders. * <A name="deliver"/>
* Queries for pending PurchaseOrders and attempts to deliver each in a separate * Delivers the given order, if it is pending.
* transaction. Some of the transactions may fail because of concurrent modification * Delivery of an order amounts to decrementing inventory for each line item
* on the inventory by the supplier. * and eventually nullify the line items to demonstrate orphan delete feature.
* <br>
* The transactions may fail because of either insufficient inventory or
* concurrent modification of the same inventory by {@link #supply(Book, int) the supplier}.
*/ */
public PurchaseOrder deliver(PurchaseOrder o) { public PurchaseOrder deliver(PurchaseOrder o) {
if (o.isDelivered())
return o;
EntityManager em = begin(); EntityManager em = begin();
o = em.merge(o); o = em.merge(o);
for (LineItem item : o.getItems()) { for (LineItem item : o.getItems()) {
@ -301,6 +326,7 @@ class OpenBookServiceImpl extends PersistenceService implements OpenBookService
} }
/** /**
* <A name="placeOrder"/>
* Creates a new {@linkplain PurchaseOrder} from the content of the given {@linkplain ShoppingCart}. * Creates a new {@linkplain PurchaseOrder} from the content of the given {@linkplain ShoppingCart}.
* The content of the cart is cleared as a result. * The content of the cart is cleared as a result.
* <br> * <br>

View File

@ -91,7 +91,7 @@ public class HTMLTokenRenderer implements TokenRenderer {
* Gets a end-of-line string: a HTML &lt;br&gt; tag followed by carriage return and line feed. * Gets a end-of-line string: a HTML &lt;br&gt; tag followed by carriage return and line feed.
*/ */
public String endLine(int line) { public String endLine(int line) {
return addLineBreak ? HTML_BR_TAG : HTML_BR_TAG + NEW_LINE; return addLineBreak ? HTML_BR_TAG + NEW_LINE : NEW_LINE;
} }
/** /**

View File

@ -105,13 +105,10 @@ public class ParseTokenListener extends BlankDebugEventListener {
public void consumeHiddenToken(Token token) { public void consumeHiddenToken(Token token) {
if (this.backtracking > 0 && currentLine != 0) return; if (this.backtracking > 0 && currentLine != 0) return;
int type = token.getType(); int type = token.getType();
if (type == JavaParser.COMMENT) { if (type == JavaParser.COMMENT || type == JavaParser.LINE_COMMENT) {
// LineBreakIterator lines = new LineBreakIterator(token.getText());
StringTokenizer linebreaker = new StringTokenizer(token.getText(), "\r\n", false); StringTokenizer linebreaker = new StringTokenizer(token.getText(), "\r\n", false);
int i = 0; int i = 0;
// for (String line : lines) {
while (linebreaker.hasMoreTokens()) { while (linebreaker.hasMoreTokens()) {
// Token dummy = new CommonToken(JavaParser.COMMENT, line);
Token dummy = new CommonToken(JavaParser.COMMENT, linebreaker.nextToken()); Token dummy = new CommonToken(JavaParser.COMMENT, linebreaker.nextToken());
changeLine(token.getLine() + i); changeLine(token.getLine() + i);
_stream.print(_renderer.render(decision, dummy)); _stream.print(_renderer.render(decision, dummy));

View File

@ -28,8 +28,8 @@ import org.antlr.runtime.Token;
*/ */
public class PlainTokenRenderer implements TokenRenderer { public class PlainTokenRenderer implements TokenRenderer {
private static final String EMPTY = ""; private static final String EMPTY = "";
private boolean showLineNumber; private boolean showLineNumber = true;
private String lineNumberFormat = "%04d :"; private String lineNumberFormat = "%04d";
public String endLine(int line) { public String endLine(int line) {
return EMPTY; return EMPTY;

View File

@ -33,11 +33,12 @@ import java.util.Date;
* *
*/ */
public class JSPUtility { public class JSPUtility {
/** /**
* Converts the given number in currency format. * Converts the given number in currency format.
*/ */
public static final DecimalFormat currencyFormatter = new DecimalFormat("###.##"); public static final DecimalFormat currencyFormatter = new DecimalFormat("###.##");
public static final DateFormat dateFormatter = new SimpleDateFormat("MMM dd yyyy HH:mm"); public static final DateFormat dateFormatter = new SimpleDateFormat("MMM dd, HH:mm");
public static String format(Number price) { public static String format(Number price) {
return currencyFormatter.format(price); return currencyFormatter.format(price);
@ -59,15 +60,6 @@ public class JSPUtility {
} }
} }
/**
* Background color of table rows.
*/
public static String EVEN_ROW_COLOR = "#E3E4FA";
public static String ODD_ROW_COLOR = "#E0FFFF";
public static String getRowStyle(int row) {
return "background-color:" + ((row % 2 == 0) ? EVEN_ROW_COLOR : ODD_ROW_COLOR);
}
/** /**
* Encodes parameter key-values in a URL. * Encodes parameter key-values in a URL.
* *
@ -104,4 +96,9 @@ public class JSPUtility {
return s; return s;
} }
} }
public static final String SRC_ROOT = "generated-html";
public static String getURL(String className, String anchor) {
return SRC_ROOT + "/" + className.replace('.', '/') + (anchor != null ? "#"+anchor : "");
}
} }