Skip to main content
Glama
java.py16.2 kB
"""Java skeleton formatter implementation""" import re from pathlib import Path from typing import List, Dict, Any, Optional from nabu.language_handlers.formatters.base import BaseSkeletonFormatter class JavaSkeletonFormatter(BaseSkeletonFormatter): """Java-specific skeleton formatter""" def format_class_skeleton( self, class_data: Dict[str, Any], methods: List[Dict[str, Any]], control_flows: Dict[str, List[Dict[str, Any]]], detail_level: str, include_docstrings: bool ) -> str: """Format Java class/interface/enum skeleton from components.""" lines = [] # Extract class declaration from content content = class_data.get("content", "") class_type = self._extract_class_type(content) # Extract class declaration line (skip annotations) declaration_line = self._extract_declaration_line(content) # Add javadoc if requested if include_docstrings and content: javadoc = self.extract_docstring(content) if javadoc: lines.append("/**") for doc_line in javadoc.split('\n'): lines.append(f" * {doc_line}" if doc_line.strip() else " *") lines.append(" */") # Add class/interface/enum declaration if declaration_line: lines.append(declaration_line) else: # Fallback: construct from metadata class_name = class_data["name"] base_classes = class_data.get("base_classes", []) if class_type == "interface": if base_classes: lines.append(f"public interface {class_name} extends {', '.join(base_classes)} {{") else: lines.append(f"public interface {class_name} {{") elif class_type == "enum": lines.append(f"public enum {class_name} {{") else: # class decl_parts = [f"public class {class_name}"] # Separate extends and implements extends = [] implements = [] for base in base_classes: # Heuristic: if base looks like interface (common suffixes/patterns) # This is imperfect but reasonable for skeleton if any(suffix in base for suffix in ['able', 'Listener', 'Interface']): implements.append(base) else: extends.append(base) if extends: decl_parts.append(f"extends {extends[0]}") # Java allows single inheritance if implements: decl_parts.append(f"implements {', '.join(implements)}") lines.append(" ".join(decl_parts) + " {") # Add enum constants placeholder if enum if class_type == "enum": lines.append(self.indent("// Enum constants", 1)) lines.append(self.indent("...", 1)) lines.append("") # Static fields static_fields = class_data.get("static_fields", []) if static_fields: lines.append("") lines.append(self.indent("// Static fields", 1)) for field in static_fields: field_name = field.get("name", "") field_type = field.get("declared_type", "Object") # Format: public static final Type NAME; (common pattern) lines.append(self.indent(f"public static final {field_type} {field_name};", 1)) # Instance fields instance_fields = class_data.get("instance_fields", []) if instance_fields: lines.append("") lines.append(self.indent("// Instance fields", 1)) for field in instance_fields: field_name = field.get("name", "") field_type = field.get("declared_type", "Object") # Format: private Type name; (common pattern for instance fields) lines.append(self.indent(f"private {field_type} {field_name};", 1)) # Methods if not methods and class_type != "enum": # Empty class (not enum) if not static_fields and not instance_fields: lines.append(self.indent("// Empty class", 1)) else: for method in methods: lines.append("") method_skeleton = self._format_method_skeleton( method=method, control_flows=control_flows.get(method["id"], []), detail_level=detail_level, include_docstrings=include_docstrings, class_name=class_data["name"] ) lines.append(method_skeleton) # Close class lines.append("}") return "\n".join(lines) def format_method_signature( self, method: Dict[str, Any], class_name: Optional[str] = None ) -> str: """Format Java method signature from metadata.""" name = method["name"] parameters = method.get("parameters", []) return_type = method.get("return_type") content = method.get("content", "") # Check if constructor is_constructor = False if class_name and self.handler.is_constructor(name, class_name): is_constructor = True # Extract modifiers and signature from content for accuracy signature_line = self._extract_declaration_line(content) if signature_line: # Use extracted signature, but ensure it ends with proper syntax # Remove opening brace if present signature_line = signature_line.rstrip().rstrip('{').rstrip() if not signature_line.endswith(';'): signature_line += ";" return signature_line # Fallback: construct from metadata # Default modifiers modifiers = ["public"] # Build parameter list param_strs = [] for param in parameters: param_name = param.get("name", "arg") param_type = param.get("declared_type", "Object") param_strs.append(f"{param_type} {param_name}") params_str = ", ".join(param_strs) # Build signature if is_constructor: # Constructor: public ClassName(params) return f"{' '.join(modifiers)} {name}({params_str});" else: # Regular method: public ReturnType methodName(params) ret_type = return_type if return_type else "void" return f"{' '.join(modifiers)} {ret_type} {name}({params_str});" def extract_docstring( self, content: str ) -> Optional[str]: """Extract Javadoc (/** ... */) from Java source.""" if not content: return None lines = content.strip().split('\n') # Look for /** ... */ pattern in_javadoc = False javadoc_lines = [] for line in lines: stripped = line.strip() if not in_javadoc: if stripped.startswith('/**'): in_javadoc = True # Check if single-line javadoc: /** text */ if stripped.endswith('*/') and len(stripped) > 5: # Single line javadoc content = stripped[3:-2].strip() # Remove leading * if present if content.startswith('*'): content = content[1:].strip() return content # Multi-line javadoc starting if len(stripped) > 3: # Has content on same line: /** content content = stripped[3:].strip() if content.startswith('*'): content = content[1:].strip() if content: javadoc_lines.append(content) else: # Inside javadoc if stripped.endswith('*/'): # End of javadoc content = stripped[:-2].strip() if content.startswith('*'): content = content[1:].strip() if content: javadoc_lines.append(content) break else: # Middle line of javadoc if stripped.startswith('*'): content = stripped[1:].strip() else: content = stripped javadoc_lines.append(content) if javadoc_lines: return "\n".join(javadoc_lines).strip() return None # ==================== PRIVATE HELPER METHODS ==================== def _format_method_skeleton( self, method: Dict[str, Any], control_flows: List[Dict[str, Any]], detail_level: str, include_docstrings: bool, class_name: str ) -> str: """Format a single Java method skeleton.""" lines = [] # Javadoc if include_docstrings and method.get("content"): javadoc = self.extract_docstring(method["content"]) if javadoc: lines.append(self.indent("/**", 1)) for doc_line in javadoc.split('\n'): lines.append(self.indent(f" * {doc_line}" if doc_line.strip() else " *", 1)) lines.append(self.indent(" */", 1)) # Method signature signature = self.format_method_signature(method, class_name) # Check if this is an abstract method or interface method content = method.get("content", "") is_abstract = 'abstract' in content or not '{' in content if is_abstract: # Abstract methods have no body lines.append(self.indent(signature, 1)) else: # Regular method with body # Remove semicolon if present and add opening brace sig_line = signature.rstrip(';').rstrip() lines.append(self.indent(sig_line + " {", 1)) # Control flow (for guards/structure modes) if detail_level != "minimal" and control_flows: control_flow_lines = self._format_control_flows( control_flows, detail_level ) lines.append(control_flow_lines) else: # Just placeholder lines.append(self.indent("...", 2)) # Close method lines.append(self.indent("}", 1)) return "\n".join(lines) def _extract_class_type(self, content: str) -> str: """ Extract whether this is a class, interface, or enum. Returns: "class", "interface", or "enum" """ if not content: return "class" lines = content.strip().split('\n') # Find first non-annotation, non-comment line for line in lines: stripped = line.strip() if stripped.startswith('@') or stripped.startswith('//') or stripped.startswith('/*'): continue # Check for keywords if ' interface ' in stripped or stripped.startswith('interface '): return "interface" elif ' enum ' in stripped or stripped.startswith('enum '): return "enum" elif ' class ' in stripped or stripped.startswith('class '): return "class" # Default return "class" def _extract_declaration_line(self, content: str) -> Optional[str]: """ Extract the complete declaration line from content. Handles multi-line declarations by concatenating until we find '{' Returns: Complete declaration line or None """ if not content: return None lines = content.strip().split('\n') # Find first non-annotation line start_idx = 0 for i, line in enumerate(lines): stripped = line.strip() if not stripped.startswith('@') and not stripped.startswith('//'): start_idx = i break # Collect lines until we find opening brace declaration_parts = [] for line in lines[start_idx:]: stripped = line.strip() if stripped.startswith('//'): continue # Skip comments declaration_parts.append(stripped) # Stop at opening brace if '{' in line: break if not declaration_parts: return None # Join and clean up declaration = ' '.join(declaration_parts) # Normalize whitespace declaration = re.sub(r'\s+', ' ', declaration).strip() return declaration def _format_docstring(self, callable_data: Dict[str, Any]) -> List[str]: """Extract Javadoc comment.""" javadoc = self.extract_docstring(callable_data["content"]) if not javadoc: return [] lines = ["/**"] for doc_line in javadoc.split('\n'): lines.append(f" * {doc_line}" if doc_line.strip() else " *") lines.append(" */") return lines def _format_empty_body_placeholder(self) -> str: """Return Java comment placeholder.""" return self.indent("// ...", 1) def _get_closing_brace(self) -> str: """Java uses closing brace.""" return "}" def format_package_skeleton( self, package_data: Dict[str, Any], children_skeletons: List[Dict[str, Any]], control_flows: List[Dict[str, Any]], detail_level: str, include_docstrings: bool ) -> str: """Format Java package skeleton.""" lines = [] # Package declaration package_name = package_data["name"] qualified_name = package_data.get("qualified_name", "") file_path = package_data.get("file_path", "") # Extract actual Java package from qualified name if possible # Java packages usually follow pattern: projectname.java_root.actual.package.name java_package = qualified_name.split(".java_root.")[-1] if ".java_root." in qualified_name else package_name lines.append(f"// Package: {java_package}") lines.append(f"// File: {Path(file_path).name}") lines.append("") lines.append(f"package {java_package};") lines.append("") # Separate children by type classes = [c for c in children_skeletons if c["frame_type"] == "CLASS"] callables = [c for c in children_skeletons if c["frame_type"] == "CALLABLE"] # Show classes if classes: lines.append("// ==================== CLASSES ====================") lines.append("") for class_skeleton in classes: lines.append(class_skeleton["skeleton"]) lines.append("") # Show top-level methods (rare in Java but possible in some contexts) if callables: lines.append("// ==================== STATIC METHODS ====================") lines.append("") for callable_skeleton in callables: lines.append(callable_skeleton["skeleton"]) lines.append("") # Package-level control flow is not typical in Java, but include if present if control_flows and detail_level != "minimal": lines.append("// ==================== INITIALIZATION ====================") lines.append("") for cf in control_flows: # Static initialization blocks at class level indent = max(0, cf.get("nesting_depth", 1) - 1) cf_hint = self.format_control_flow_hint(cf, detail_level, indent_level=indent) if cf_hint: lines.append(cf_hint) return "\n".join(lines)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/y3i12/nabu_nisaba'

If you have feedback or need assistance with the MCP directory API, please join our Discord server